From 1f27f9b50b6c60b242f170c657316b328b4b704d Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 1 Oct 2013 19:14:24 +0000 Subject: [PATCH 01/11] Pull in r191711 from upstream llvm trunk: The X86FixupLEAs pass for Intel Atom must not call convertToThreeAddress on ADD16rr opcodes, if src1 != src, since that would cause convertToThreeAddress to try to create a virtual register. This is not permitted after register allocation, which is when the X86FixupLEAs pass runs. This patch fixes PR16785. Pull in r191715 from upstream llvm trunk: Forgot to add a break statement. This should enable building the x11-toolskits/libXaw port with CPUTYPE=atom. Approved by: re (gjb) Reported by: Kenta Suzumoto MFC after: 3 days --- contrib/llvm/lib/Target/X86/X86FixupLEAs.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/contrib/llvm/lib/Target/X86/X86FixupLEAs.cpp b/contrib/llvm/lib/Target/X86/X86FixupLEAs.cpp index 0dd034c4509..e8c88a311de 100644 --- a/contrib/llvm/lib/Target/X86/X86FixupLEAs.cpp +++ b/contrib/llvm/lib/Target/X86/X86FixupLEAs.cpp @@ -125,6 +125,15 @@ FixupLEAPass::postRAConvertToLEA(MachineFunction::iterator &MFI, // which requires isImm() to be true return 0; } + break; + case X86::ADD16rr: + case X86::ADD16rr_DB: + if (MI->getOperand(1).getReg() != MI->getOperand(2).getReg()) { + // if src1 != src2, then convertToThreeAddress will + // need to create a Virtual register, which we cannot do + // after register allocation. + return 0; + } } return TII->convertToThreeAddress(MFI, MBBI, 0); } From d6498b153ea68aa82ba227551caf48569e6379bc Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 1 Oct 2013 20:18:33 +0000 Subject: [PATCH 02/11] When printing the vnode information from ddb, print the lengths of the dirty and clean buffer queues. Sponsored by: The FreeBSD Foundation MFC after: 1 week Approved by: re (gjb) --- sys/kern/vfs_subr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 952a48990d2..930a3c8f478 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2892,9 +2892,12 @@ vn_printf(struct vnode *vp, const char *fmt, ...) if (mtx_owned(VI_MTX(vp))) printf(" VI_LOCKed"); if (vp->v_object != NULL) - printf(" v_object %p ref %d pages %d\n", + printf(" v_object %p ref %d pages %d " + "cleanbuf %d dirtybuf %d\n", vp->v_object, vp->v_object->ref_count, - vp->v_object->resident_page_count); + vp->v_object->resident_page_count, + vp->v_bufobj.bo_dirty.bv_cnt, + vp->v_bufobj.bo_clean.bv_cnt); printf(" "); lockmgr_printinfo(vp->v_vnlock); if (vp->v_data != NULL) From 0f49c96cfc484c26d9153727b7d929d1e353993e Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Tue, 1 Oct 2013 21:17:18 +0000 Subject: [PATCH 03/11] accept(2): Update portability note for accept4(). The accept(2) man page warns that O_NONBLOCK and other properties on the new socket may vary across implementations. However, this issue only applies to accept() and not to accept4(). On the other hand, accept4() is not commonly available yet. Reported by: pluknet Reviewed by: bjk Approved by: re (kib) --- lib/libc/sys/accept.2 | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2 index 76fb463a1ef..7b8422a0552 100644 --- a/lib/libc/sys/accept.2 +++ b/lib/libc/sys/accept.2 @@ -28,7 +28,7 @@ .\" @(#)accept.2 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd May 1, 2013 +.Dd October 1, 2013 .Dt ACCEPT 2 .Os .Sh NAME @@ -155,13 +155,20 @@ For some applications, performance may be enhanced by using an .Xr accept_filter 9 to pre-process incoming connections. .Pp -Portable programs should not rely on the +When using +.Fn accept , +portable programs should not rely on the .Dv O_NONBLOCK and .Dv O_ASYNC properties and the signal destination being inherited, but should set them explicitly using -.Xr fcntl 2 . +.Xr fcntl 2 ; +.Fn accept4 +sets these properties consistently, +but may not be fully portable across +.Ux +platforms. .Sh RETURN VALUES These calls return \-1 on error. If they succeed, they return a non-negative From 5bab73677e42ba68b0982b79870435b2bcfe4d52 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 1 Oct 2013 22:53:27 +0000 Subject: [PATCH 04/11] Revert-and-redo r255955: the sort -r should be added to delete-old-dirs. Approved by: re (gjb) --- Makefile.inc1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 5fed30e057f..ac10c2b1412 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1673,7 +1673,7 @@ delete-old-files: # the Makefile parser segfault. @exec 3<&0; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ - -V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | sort -r | \ + -V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \ @@ -1738,7 +1738,7 @@ check-old-libs: delete-old-dirs: @echo ">>> Removing old directories" @${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ - -V OLD_DIRS | xargs -n1 | \ + -V OLD_DIRS | xargs -n1 | sort -r | \ while read dir; do \ if [ -d "${DESTDIR}/$${dir}" ]; then \ rmdir -v "${DESTDIR}/$${dir}" || true; \ From 36afc9ab6c1c7fdb2e40bdcfde169501d962dd84 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 2 Oct 2013 00:50:27 +0000 Subject: [PATCH 05/11] Use correct size for MIPS .rld_map section On MIPS .dynamic is read-only and so a special section .rld_map is used to store the pointer to the rtld information for debuggers. This section had a hard coded size of 4 bytes which is not correct for mips64. (Note that FreeBSD's rtld does not yet populate .rld_map.) Sponsored by: DARPA, AFRL Approved by: re (delphij) --- contrib/binutils/bfd/elfxx-mips.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/binutils/bfd/elfxx-mips.c b/contrib/binutils/bfd/elfxx-mips.c index eac685ff0ab..8f4b05d0687 100644 --- a/contrib/binutils/bfd/elfxx-mips.c +++ b/contrib/binutils/bfd/elfxx-mips.c @@ -557,6 +557,10 @@ static bfd *reldyn_sorting_bfd; #define MIPS_ELF_DYN_SIZE(abfd) \ (get_elf_backend_data (abfd)->s->sizeof_dyn) +/* The size of the rld_map pointer. */ +#define MIPS_ELF_RLD_MAP_SIZE(abfd) \ + (get_elf_backend_data (abfd)->s->arch_size / 8) + /* The size of a GOT entry. */ #define MIPS_ELF_GOT_SIZE(abfd) \ (get_elf_backend_data (abfd)->s->arch_size / 8) @@ -7492,7 +7496,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, { /* We add a room for __rld_map. It will be filled in by the rtld to contain a pointer to the _r_debug structure. */ - s->size += 4; + s->size += MIPS_ELF_RLD_MAP_SIZE (output_bfd); } else if (SGI_COMPAT (output_bfd) && CONST_STRNEQ (name, ".compact_rel")) From d24aca1b006c350085024b90eb5610474c831124 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 2 Oct 2013 02:32:58 +0000 Subject: [PATCH 06/11] Populate .rld_map on MIPS for debuggers On MIPS the .dynamic section is read-only, so the pointer to rtld information for debuggers cannot be stored there (in DT_DEBUG). Instead, a special section .rld_map is used. Sponsored by: DARPA, AFRL Approved by: re (delphij) --- libexec/rtld-elf/rtld.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index cd18bad0013..f690d75f134 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -1111,11 +1111,7 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath, break; case DT_MIPS_RLD_MAP: -#ifdef notyet - if (!early) - dbg("Filling in DT_DEBUG entry"); - ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug; -#endif + *((Elf_Addr *)(dynp->d_un.d_ptr)) = (Elf_Addr) &r_debug; break; #endif From 5bbecb65b8f5a785d6c252866a0f04da48be5f9c Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Wed, 2 Oct 2013 04:40:46 +0000 Subject: [PATCH 07/11] Add FreeBSD 9.2-RELEASE to the BSD Family Tree Approved by: re (hrs) Sponsored by: The FreeBSD Foundation --- share/misc/bsd-family-tree | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree index 0ee60a38781..7d0ae943808 100644 --- a/share/misc/bsd-family-tree +++ b/share/misc/bsd-family-tree @@ -263,22 +263,23 @@ FreeBSD 5.2 | | | | | | | | | | | | OpenBSD 5.2 DragonFly 3.2.1 | FreeBSD | | | | | NetBSD | | | 9.1 | | | | | 5.2 | | - | | | | | | | | | - | | | | | | NetBSD | | - | | | | | | 5.2.1 | | - | | | | | | | | - | | | | | \ | | - | | | | | NetBSD | | - | | | | | 6.0.1 | | - | | | | | | OpenBSD 5.3 DragonFly 3.4.1 - | | | | | NetBSD | | - | | | | | 6.0.2 | | - | | | | | | | - | | | | `-NetBSD 6.1 | | - | FreeBSD | | | | - | 8.4 | | | | - | | | | | - | | | | | + | | | | | | | | | | + | | | | | | | NetBSD | | + | | | | | | | 5.2.1 | | + | | | | | | | | | + | | | | | | \ | | + | | | | | | NetBSD | | + | | | | | | 6.0.1 | | + | | | | | | | OpenBSD 5.3 DragonFly 3.4.1 + | | | | | | NetBSD | | + | | | | | | 6.0.2 | | + | | | | | | | | + | | | | | `-NetBSD 6.1 | | + | | FreeBSD | | | | + | | 8.4 | | | | + | | | | | | + | FreeBSD | | | | + | 9.2 | | | | | | | | | FreeBSD 10 -current | NetBSD -current OpenBSD -current | | | | | | @@ -589,6 +590,7 @@ NetBSD 6.1 2013-05-18 [NBD] FreeBSD 8.4 2013-06-07 [FBD] NetBSD 5.1.3 2013-09-29 [NBD] NetBSD 5.2.1 2013-09-29 [NBD] +FreeBSD 9.2 2013-09-30 [FBD] Bibliography ------------------------ From 432e79fc3380cdf6092ec37cdd7d78433e86c488 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 2 Oct 2013 06:00:34 +0000 Subject: [PATCH 08/11] When helping the bufdaemon from the buffer allocation context, there is no sense to walk the whole dirty buffer queue. We are only interested in, and can operate on, the buffers owned by the current vnode [1]. Instead of calling generic queue flush routine, do VOP_FSYNC() if possible. Holding the dirty buffer queue lock in the bufdaemon, without dropping it, can cause starvation of buffer writes from other threads. This is esp. easy to reproduce on the big memory machines, where large files are written, causing almost all dirty buffers accumulating in several big files, which vnodes are locked by writers. Bufdaemon cannot flush any buffer, but is iterating over the whole dirty queue continuously. Since dirty queue mutex is not dropped, bufdone() in g_up thread is starved, usually deadlocking the machine [2]. Mitigate this by dropping the queue lock after the vnode is locked, allowing other queue lock contenders to make a progress. Discussed with: Jeff [1] Reported by: pho [2] Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Approved by: re (hrs) --- sys/kern/vfs_bio.c | 104 ++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 8787f511fab..1690ee5a05e 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -113,8 +113,8 @@ static void vfs_setdirty_locked_object(struct buf *bp); static void vfs_vmio_release(struct buf *bp); static int vfs_bio_clcheck(struct vnode *vp, int size, daddr_t lblkno, daddr_t blkno); -static int buf_flush(struct vnode *vp, int); -static int flushbufqueues(struct vnode *, int, int); +static int buf_flush(int); +static int flushbufqueues(int, int); static void buf_daemon(void); static void bremfreel(struct buf *bp); static __inline void bd_wakeup(void); @@ -2048,7 +2048,7 @@ getnewbuf_bufd_help(struct vnode *vp, int gbflags, int slpflag, int slptimeo, { struct thread *td; char *waitmsg; - int fl, flags, norunbuf; + int cnt, error, flags, norunbuf, wait; mtx_assert(&bqclean, MA_OWNED); @@ -2072,10 +2072,13 @@ getnewbuf_bufd_help(struct vnode *vp, int gbflags, int slpflag, int slptimeo, return; td = curthread; + cnt = 0; + wait = MNT_NOWAIT; mtx_lock(&nblock); while (needsbuffer & flags) { if (vp != NULL && (td->td_pflags & TDP_BUFNEED) == 0) { mtx_unlock(&nblock); + /* * getblk() is called with a vnode locked, and * some majority of the dirty buffers may as @@ -2084,15 +2087,20 @@ getnewbuf_bufd_help(struct vnode *vp, int gbflags, int slpflag, int slptimeo, * cannot be achieved by the buf_daemon, that * cannot lock the vnode. */ - norunbuf = ~(TDP_BUFNEED | TDP_NORUNNINGBUF) | - (td->td_pflags & TDP_NORUNNINGBUF); - /* play bufdaemon */ - td->td_pflags |= TDP_BUFNEED | TDP_NORUNNINGBUF; - fl = buf_flush(vp, flushbufqtarget); - td->td_pflags &= norunbuf; + if (cnt++ > 2) + wait = MNT_WAIT; + ASSERT_VOP_LOCKED(vp, "bufd_helper"); + error = VOP_ISLOCKED(vp) == LK_EXCLUSIVE ? 0 : + vn_lock(vp, LK_TRYUPGRADE); + if (error == 0) { + /* play bufdaemon */ + norunbuf = curthread_pflags_set(TDP_BUFNEED | + TDP_NORUNNINGBUF); + VOP_FSYNC(vp, wait, td); + atomic_add_long(¬bufdflushes, 1); + curthread_pflags_restore(norunbuf); + } mtx_lock(&nblock); - if (fl != 0) - continue; if ((needsbuffer & flags) == 0) break; } @@ -2510,20 +2518,18 @@ static struct kproc_desc buf_kp = { SYSINIT(bufdaemon, SI_SUB_KTHREAD_BUF, SI_ORDER_FIRST, kproc_start, &buf_kp); static int -buf_flush(struct vnode *vp, int target) +buf_flush(int target) { int flushed; - flushed = flushbufqueues(vp, target, 0); + flushed = flushbufqueues(target, 0); if (flushed == 0) { /* * Could not find any buffers without rollback * dependencies, so just write the first one * in the hopes of eventually making progress. */ - if (vp != NULL && target > 2) - target /= 2; - flushbufqueues(vp, target, 1); + flushed = flushbufqueues(target, 1); } return (flushed); } @@ -2560,7 +2566,7 @@ buf_daemon() * the I/O system. */ while (numdirtybuffers > lodirty) { - if (buf_flush(NULL, numdirtybuffers - lodirty) == 0) + if (buf_flush(numdirtybuffers - lodirty) == 0) break; kern_yield(PRI_USER); } @@ -2615,7 +2621,7 @@ SYSCTL_INT(_vfs, OID_AUTO, flushwithdeps, CTLFLAG_RW, &flushwithdeps, 0, "Number of buffers flushed with dependecies that require rollbacks"); static int -flushbufqueues(struct vnode *lvp, int target, int flushdeps) +flushbufqueues(int target, int flushdeps) { struct buf *sentinel; struct vnode *vp; @@ -2625,7 +2631,6 @@ flushbufqueues(struct vnode *lvp, int target, int flushdeps) int flushed; int queue; int error; - bool unlock; flushed = 0; queue = QUEUE_DIRTY; @@ -2634,27 +2639,24 @@ flushbufqueues(struct vnode *lvp, int target, int flushdeps) sentinel->b_qindex = QUEUE_SENTINEL; mtx_lock(&bqdirty); TAILQ_INSERT_HEAD(&bufqueues[queue], sentinel, b_freelist); + mtx_unlock(&bqdirty); while (flushed != target) { + maybe_yield(); + mtx_lock(&bqdirty); bp = TAILQ_NEXT(sentinel, b_freelist); if (bp != NULL) { TAILQ_REMOVE(&bufqueues[queue], sentinel, b_freelist); TAILQ_INSERT_AFTER(&bufqueues[queue], bp, sentinel, b_freelist); - } else + } else { + mtx_unlock(&bqdirty); break; - /* - * Skip sentinels inserted by other invocations of the - * flushbufqueues(), taking care to not reorder them. - */ - if (bp->b_qindex == QUEUE_SENTINEL) - continue; - /* - * Only flush the buffers that belong to the - * vnode locked by the curthread. - */ - if (lvp != NULL && bp->b_vp != lvp) - continue; - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL) != 0) + } + KASSERT(bp->b_qindex != QUEUE_SENTINEL, + ("parallel calls to flushbufqueues() bp %p", bp)); + error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL); + mtx_unlock(&bqdirty); + if (error != 0) continue; if (bp->b_pin_count > 0) { BUF_UNLOCK(bp); @@ -2670,11 +2672,9 @@ flushbufqueues(struct vnode *lvp, int target, int flushdeps) continue; } if (bp->b_flags & B_INVAL) { - bremfreel(bp); - mtx_unlock(&bqdirty); + bremfreef(bp); brelse(bp); flushed++; - mtx_lock(&bqdirty); continue; } @@ -2701,45 +2701,23 @@ flushbufqueues(struct vnode *lvp, int target, int flushdeps) BUF_UNLOCK(bp); continue; } - if (lvp == NULL) { - unlock = true; - error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT); - } else { - ASSERT_VOP_LOCKED(vp, "getbuf"); - unlock = false; - error = VOP_ISLOCKED(vp) == LK_EXCLUSIVE ? 0 : - vn_lock(vp, LK_TRYUPGRADE); - } + error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT); if (error == 0) { - mtx_unlock(&bqdirty); CTR3(KTR_BUF, "flushbufqueue(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags); - if (curproc == bufdaemonproc) - vfs_bio_awrite(bp); - else { - bremfree(bp); - bwrite(bp); - notbufdflushes++; - } + vfs_bio_awrite(bp); vn_finished_write(mp); - if (unlock) - VOP_UNLOCK(vp, 0); + VOP_UNLOCK(vp, 0); flushwithdeps += hasdeps; flushed++; - - /* - * Sleeping on runningbufspace while holding - * vnode lock leads to deadlock. - */ - if (curproc == bufdaemonproc && - runningbufspace > hirunningspace) + if (runningbufspace > hirunningspace) waitrunningbufspace(); - mtx_lock(&bqdirty); continue; } vn_finished_write(mp); BUF_UNLOCK(bp); } + mtx_lock(&bqdirty); TAILQ_REMOVE(&bufqueues[queue], sentinel, b_freelist); mtx_unlock(&bqdirty); free(sentinel, M_TEMP); From 4f835517e57711b57b96e5c205f66f9f977044d4 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Wed, 2 Oct 2013 13:33:10 +0000 Subject: [PATCH 09/11] Only build the POWER hypervisor UART driver if device uart is included in the kernel config. Approved by: re (gjb) --- sys/conf/files.powerpc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index fe9f8764333..f714987989a 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -227,7 +227,7 @@ powerpc/ps3/ps3_syscons.c optional ps3 sc powerpc/ps3/ps3-hvcall.S optional ps3 sc powerpc/pseries/phyp-hvcall.S optional pseries powerpc64 powerpc/pseries/mmu_phyp.c optional pseries powerpc64 -powerpc/pseries/phyp_console.c optional pseries powerpc64 +powerpc/pseries/phyp_console.c optional pseries powerpc64 uart powerpc/pseries/phyp_vscsi.c optional pseries powerpc64 scbus powerpc/pseries/platform_chrp.c optional pseries powerpc/pseries/plpar_iommu.c optional pseries powerpc64 From 5c4d5cc7959ff51a942af288cebc6e96ed1e797e Mon Sep 17 00:00:00 2001 From: Sean Bruno Date: Wed, 2 Oct 2013 14:43:17 +0000 Subject: [PATCH 10/11] set ROOTDEVNAME to ada0 with no paritions. This makes it much more functional with makefs and other tools for testing and ports building Approved by: re (gjb) MFC after: 2 weeks --- sys/mips/conf/MALTA | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/conf/MALTA b/sys/mips/conf/MALTA index ab9d38da44f..fc082ad994a 100644 --- a/sys/mips/conf/MALTA +++ b/sys/mips/conf/MALTA @@ -51,7 +51,7 @@ options FFS #Berkeley Fast Filesystem options SOFTUPDATES #Enable FFS soft updates support options UFS_ACL #Support for access control lists options UFS_DIRHASH #Improve performance on big directories -options ROOTDEVNAME=\"ufs:ada0s1a\" +options ROOTDEVNAME=\"ufs:ada0\" # Debugging for use in -current From 8298c17c6c98d5beb96edbf9be046d6009cf3011 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 2 Oct 2013 17:14:12 +0000 Subject: [PATCH 11/11] Add a separate translator for headers passed to the TCP probes in the input path. These probes get some of the fields in host order, whereas the output probes get them in network order, so a single translator isn't enough. This workaround ensures that the problem is essentially invisble to users: none of the probe arguments or their fields have changed. Approved by: re (hrs) --- cddl/lib/libdtrace/tcp.d | 40 +++++++++++++++++++++++++++++++++++++++- sys/netinet/in_kdtrace.c | 8 ++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/cddl/lib/libdtrace/tcp.d b/cddl/lib/libdtrace/tcp.d index 6d56eb7fca3..4204507dc3e 100644 --- a/cddl/lib/libdtrace/tcp.d +++ b/cddl/lib/libdtrace/tcp.d @@ -141,6 +141,25 @@ typedef struct tcpinfo { struct tcphdr *tcp_hdr; /* raw TCP header */ } tcpinfo_t; +/* + * A clone of tcpinfo_t used to handle the fact that the TCP input path + * overwrites some fields of the TCP header with their host-order equivalents. + * Unfortunately, DTrace doesn't let us simply typedef a new name for struct + * tcpinfo and define a separate translator for it. + */ +typedef struct tcpinfoh { + uint16_t tcp_sport; /* source port */ + uint16_t tcp_dport; /* destination port */ + uint32_t tcp_seq; /* sequence number */ + uint32_t tcp_ack; /* acknowledgment number */ + uint8_t tcp_offset; /* data offset, in bytes */ + uint8_t tcp_flags; /* flags */ + uint16_t tcp_window; /* window size */ + uint16_t tcp_checksum; /* checksum */ + uint16_t tcp_urgent; /* urgent data pointer */ + struct tcphdr *tcp_hdr; /* raw TCP header */ +} tcpinfoh_t; + #pragma D binding "1.0" translator translator csinfo_t < struct tcpcb *p > { cs_addr = NULL; @@ -180,7 +199,7 @@ translator tcpsinfo_t < struct tcpcb *p > { tcps_sack_snxt = p == NULL ? 0 : p->sack_newdata; tcps_rto = p == NULL ? -1 : p->t_rxtcur / 1000; /* XXX */ tcps_mss = p == NULL ? -1 : p->t_maxseg; - tcps_retransmit = -1; /* XXX */ + tcps_retransmit = p == NULL ? -1 : p->t_rxtshift > 0 ? 1 : 0; }; #pragma D binding "1.0" translator @@ -197,6 +216,25 @@ translator tcpinfo_t < struct tcphdr *p > { tcp_hdr = (struct tcphdr *)p; }; +/* + * This translator differs from the one for tcpinfo_t in that the sequence + * number, acknowledgement number, window size and urgent pointer are already + * in host order and thus don't need to be converted. + */ +#pragma D binding "1.0" translator +translator tcpinfoh_t < struct tcphdr *p > { + tcp_sport = p == NULL ? 0 : ntohs(p->th_sport); + tcp_dport = p == NULL ? 0 : ntohs(p->th_dport); + tcp_seq = p == NULL ? -1 : p->th_seq; + tcp_ack = p == NULL ? -1 : p->th_ack; + tcp_offset = p == NULL ? -1 : (p->th_off >> 2); + tcp_flags = p == NULL ? 0 : p->th_flags; + tcp_window = p == NULL ? 0 : (p->th_win); + tcp_checksum = p == NULL ? 0 : ntohs(p->th_sum); + tcp_urgent = p == NULL ? 0 : p->th_urp; + tcp_hdr = (struct tcphdr *)p; +}; + #pragma D binding "1.0" translator translator tcplsinfo_t < int s > { tcps_state = s; diff --git a/sys/netinet/in_kdtrace.c b/sys/netinet/in_kdtrace.c index 85a5a4ead49..fc39e4396de 100644 --- a/sys/netinet/in_kdtrace.c +++ b/sys/netinet/in_kdtrace.c @@ -60,7 +60,7 @@ SDT_PROBE_DEFINE5_XLATE(tcp, , , accept_established, accept-established, "struct tcpcb *", "csinfo_t *", "uint8_t *", "ipinfo_t *", "struct tcpcb *", "tcpsinfo_t *" , - "struct tcphdr *", "tcpinfo_t *"); + "struct tcphdr *", "tcpinfoh_t *"); SDT_PROBE_DEFINE5_XLATE(tcp, , , accept_refused, accept-refused, "void *", "pktinfo_t *", @@ -74,14 +74,14 @@ SDT_PROBE_DEFINE5_XLATE(tcp, , , connect_established, connect-established, "struct tcpcb *", "csinfo_t *", "uint8_t *", "ipinfo_t *", "struct tcpcb *", "tcpsinfo_t *" , - "struct tcphdr *", "tcpinfo_t *"); + "struct tcphdr *", "tcpinfoh_t *"); SDT_PROBE_DEFINE5_XLATE(tcp, , , connect_refused, connect-refused, "void *", "pktinfo_t *", "struct tcpcb *", "csinfo_t *", "uint8_t *", "ipinfo_t *", "struct tcpcb *", "tcpsinfo_t *" , - "struct tcphdr *", "tcpinfo_t *"); + "struct tcphdr *", "tcpinfoh_t *"); SDT_PROBE_DEFINE5_XLATE(tcp, , , connect_request, connect-request, "void *", "pktinfo_t *", @@ -95,7 +95,7 @@ SDT_PROBE_DEFINE5_XLATE(tcp, , , receive, receive, "struct tcpcb *", "csinfo_t *", "uint8_t *", "ipinfo_t *", "struct tcpcb *", "tcpsinfo_t *" , - "struct tcphdr *", "tcpinfo_t *"); + "struct tcphdr *", "tcpinfoh_t *"); SDT_PROBE_DEFINE5_XLATE(tcp, , , send, send, "void *", "pktinfo_t *",