# -------- ----- -------- ---------------
# BASE = [ intel mach medium config_dtrace vol pst gdb kernobjc fixpri simple_clock mdebug kernserv driverkit uxpr kernstack ipc_compat ipc_debug sysv_sem sysv_msg sysv_shm audit panic_info config_imageboot config_workqueue psynch ]
# FILESYS = [ devfs revfs hfs journaling fdesc config_fse quota namedstreams fifo union config_volfs hfs_compression config_imgsrc_access ]
-# NETWORKING = [ inet inet6 compat_oldsock tcpdrop_synfin bpfilter ipdivert ipfirewall ipv6firewall ipfw2 dummynet traffic_mgt sendfile netmibs bond vlan gif stf zlib randomipid ifnet_input_chk config_mbuf_jumbo ipflow ]
+# NETWORKING = [ inet inet6 compat_oldsock tcpdrop_synfin bpfilter ipdivert ipfirewall ipv6firewall ipfw2 dummynet traffic_mgt sendfile netmibs bond vlan gif stf zlib randomipid ifnet_input_chk config_mbuf_jumbo ipflow pkt_priority if_bridge ]
# NFS = [ nfsclient nfsserver ]
# VPN = [ ipsec ]
# RELEASE = [ BASE NETWORKING NFS VPN FILESYS libdriver ]
#
# BASE = [ ppc mach medium config_dtrace vol pst gdb noprofiling simple_clock kernstack sysv_sem sysv_msg sysv_shm audit panic_info config_imageboot config_workqueue ]
# FILESYS = [ devfs revfs hfs journaling fdesc config_fse quota namedstreams fifo union config_volfs hfs_compression ]
-# NETWORKING = [ inet inet6 compat_oldsock tcpdrop_synfin bpfilter ipdivert ipfirewall ipv6firewall ipfw2 dummynet traffic_mgt sendfile netmibs bond vlan gif stf zlib randomipid ifnet_input_chk ipflow ]
+# NETWORKING = [ inet inet6 compat_oldsock tcpdrop_synfin bpfilter ipdivert ipfirewall ipv6firewall ipfw2 dummynet traffic_mgt sendfile netmibs bond vlan gif stf zlib randomipid ifnet_input_chk ipflow pkt_priority ]
# NFS = [ nfsclient nfsserver ]
# VPN = [ ipsec ]
# RELEASE = [ BASE NETWORKING NFS VPN FILESYS libdriver ]
# -------- ----- -------- ---------------
# BASE = [ intel mach medium config_dtrace vol pst gdb kernobjc fixpri simple_clock mdebug kernserv driverkit uxpr kernstack ipc_compat ipc_debug sysv_sem sysv_msg sysv_shm audit panic_info config_imageboot config_workqueue psynch ]
# FILESYS = [ devfs revfs hfs journaling fdesc config_fse quota namedstreams fifo union config_volfs hfs_compression config_imgsrc_access ]
-# NETWORKING = [ inet inet6 compat_oldsock tcpdrop_synfin bpfilter ipdivert ipfirewall ipv6firewall ipfw2 dummynet traffic_mgt sendfile netmibs bond vlan gif stf zlib randomipid ifnet_input_chk config_mbuf_jumbo ipflow ]
+# NETWORKING = [ inet inet6 compat_oldsock tcpdrop_synfin bpfilter ipdivert ipfirewall ipv6firewall ipfw2 dummynet traffic_mgt sendfile netmibs bond vlan gif stf zlib randomipid ifnet_input_chk config_mbuf_jumbo ipflow pkt_priority if_bridge ]
# NFS = [ nfsclient nfsserver ]
# VPN = [ ipsec ]
# RELEASE = [ BASE NETWORKING NFS VPN FILESYS libdriver ]
/*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
UniChar uniStr[MAX_HFS_UNICODE_CHARS];
ItemCount uniCount;
size_t utf8len;
+ u_int8_t pascal_length = 0;
hfs_to_unicode_func_t hfs_get_unicode = VCBTOHFS(vcb)->hfs_get_unicode;
+ /*
+ * Validate the length of the Pascal-style string before passing it
+ * down to the decoding engine.
+ */
+ pascal_length = *((const u_int8_t*)(hfs_str));
+ if (pascal_length > 31) {
+ /* invalid string; longer than 31 bytes */
+ error = EINVAL;
+ return error;
+ }
+
error = hfs_get_unicode(hfs_str, uniStr, MAX_HFS_UNICODE_CHARS, &uniCount);
if (uniCount == 0)
UniChar uniStr[MAX_HFS_UNICODE_CHARS];
ItemCount uniCount;
size_t utf8len;
+ u_int8_t pascal_length = 0;
+
+ /*
+ * Validate the length of the Pascal-style string before passing it
+ * down to the decoding engine.
+ */
+ pascal_length = *((const u_int8_t*)(hfs_str));
+ if (pascal_length > 31) {
+ /* invalid string; longer than 31 bytes */
+ error = EINVAL;
+ return error;
+ }
error = mac_roman_to_unicode(hfs_str, uniStr, MAX_HFS_UNICODE_CHARS, &uniCount);
user_bootstrap.fbt_length = bootstrapp->fbt_length;
user_bootstrap.fbt_buffer = CAST_USER_ADDR_T(bootstrapp->fbt_buffer);
}
+
+ if ((user_bootstrapp->fbt_offset < 0) || (user_bootstrapp->fbt_offset > 1024) ||
+ (user_bootstrapp->fbt_length > 1024)) {
+ return EINVAL;
+ }
+
if (user_bootstrapp->fbt_offset + user_bootstrapp->fbt_length > 1024)
return EINVAL;
* When an HFS name cannot be encoded with the current
* volume encoding we use MacRoman as a fallback.
*/
- if (error || (utf8chars == 0))
+ if (error || (utf8chars == 0)) {
(void) mac_roman_to_utf8(mdb->drVN, NAME_MAX, &utf8chars, vcb->vcbVN);
-
+ /* If we fail to encode to UTF8 from Mac Roman, the name is bad. Deny mount */
+ if (error) {
+ goto MtVolErr;
+ }
+ }
hfsmp->hfs_logBlockSize = BestBlockSizeFit(vcb->blockSize, MAXBSIZE, hfsmp->hfs_logical_block_size);
vcb->vcbVBMIOSize = kHFSBlockSize;
}
hfsmp->hfs_allocation_cp = VTOC(hfsmp->hfs_allocation_vp);
- /* mark the volume dirty (clear clean unmount bit) */
+ /* mark the volume dirty (clear clean unmount bit) */
vcb->vcbAtrb &= ~kHFSVolumeUnmountedMask;
if (error == noErr)
hfs_unlock(VTOC(hfsmp->hfs_catalog_vp));
hfs_unlock(VTOC(hfsmp->hfs_extents_vp));
- goto CmdDone;
+ if (error == noErr) {
+ /* If successful, then we can just return once we've unlocked the cnodes */
+ return error;
+ }
//-- Release any resources allocated so far before exiting with an error:
MtVolErr:
ReleaseMetaFileVNode(hfsmp->hfs_catalog_vp);
ReleaseMetaFileVNode(hfsmp->hfs_extents_vp);
+ ReleaseMetaFileVNode(hfsmp->hfs_allocation_vp);
-CmdDone:
return (error);
}
#include <kern/thread.h>
#include <kern/task.h>
#include <kern/debug.h>
+#include <kern/assert.h>
#include <vm/vm_kern.h>
#include <sys/lock.h>
#define TRAP_DEBUGGER __asm__ volatile("tw 4,r3,r3");
#endif
-#define SANE_TRACEBUF_SIZE 2*1024*1024
+#define SANE_TRACEBUF_SIZE (8 * 1024 * 1024)
/* Initialize the mutex governing access to the stack snapshot subsystem */
__private_extern__ void
{
int error = 0;
unsigned bytesTraced = 0;
+ boolean_t istate;
*retval = -1;
/* Serialize tracing */
goto error_exit;
}
- MALLOC(stackshot_snapbuf, void *, tracebuf_size, M_TEMP, M_WAITOK);
+ assert(stackshot_snapbuf == NULL);
+ if (kmem_alloc_kobject(kernel_map, (vm_offset_t *)&stackshot_snapbuf, tracebuf_size) != KERN_SUCCESS) {
+ error = ENOMEM;
+ goto error_exit;
+ }
- if (stackshot_snapbuf == NULL) {
+ if (panic_active()) {
error = ENOMEM;
goto error_exit;
}
+
+ istate = ml_set_interrupts_enabled(FALSE);
/* Preload trace parameters*/
kdp_snapshot_preflight(pid, stackshot_snapbuf, tracebuf_size, flags, dispatch_offset);
/* Trap to the debugger to obtain a coherent stack snapshot; this populates
* the trace buffer
*/
- if (panic_active()) {
- error = ENOMEM;
- goto error_exit;
- }
TRAP_DEBUGGER;
+ ml_set_interrupts_enabled(istate);
+
bytesTraced = kdp_stack_snapshot_bytes_traced();
if (bytesTraced > 0) {
error_exit:
if (stackshot_snapbuf != NULL)
- FREE(stackshot_snapbuf, M_TEMP);
+ kmem_free(kernel_map, (vm_offset_t) stackshot_snapbuf, tracebuf_size);
stackshot_snapbuf = NULL;
STACKSHOT_SUBSYS_UNLOCK();
return error;
/*
- * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
return (prio);
#endif /* PKT_PRIORITY */
}
+
+mbuf_traffic_class_t
+mbuf_get_traffic_class(mbuf_t m)
+{
+#if !PKT_PRIORITY
+#pragma unused(m)
+ return (MBUF_TC_BE);
+#else /* PKT_PRIORITY */
+ mbuf_priority_t prio = MBUF_TC_BE;
+
+ if (m == NULL || !(m->m_flags & M_PKTHDR))
+ return (prio);
+
+ if (m->m_pkthdr.prio <= MBUF_TC_VO)
+ prio = m->m_pkthdr.prio;
+
+ return (prio);
+#endif /* PKT_PRIORITY */
+}
+
+errno_t
+mbuf_set_traffic_class(mbuf_t m, mbuf_traffic_class_t tc)
+{
+#if !PKT_PRIORITY
+#pragma unused(m)
+#pragma unused(tc)
+ return 0;
+#else /* PKT_PRIORITY */
+ errno_t error = 0;
+
+ if (m == NULL || !(m->m_flags & M_PKTHDR))
+ return EINVAL;
+
+ switch (tc) {
+ case MBUF_TC_BE:
+ case MBUF_TC_BK:
+ case MBUF_TC_VI:
+ case MBUF_TC_VO:
+ m->m_pkthdr.prio = tc;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return error;
+#endif /* PKT_PRIORITY */
+}
/*
- * Copyright (c) 2003-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
{
(void) OSBitAndAtomic(~flags, &sock->so_traffic_mgt_flags);
}
+
+__private_extern__ void
+set_traffic_class(struct mbuf *m, struct socket *so, int mtc)
+{
+#if !PKT_PRIORITY
+#pragma unused(m)
+#pragma unused(so)
+#pragma unused(mtc)
+ return;
+#else /* PKT_PRIORITY */
+ if (!(m->m_flags & M_PKTHDR))
+ return;
+
+ if (soisbackground(so)) {
+ m->m_pkthdr.prio = MBUF_TC_BK;
+ } else if (mtc != MBUF_TC_NONE) {
+ if (mtc >= MBUF_TC_BE && mtc <= MBUF_TC_VO)
+ m->m_pkthdr.prio = mtc;
+ } else {
+ switch (so->so_traffic_class) {
+ case SO_TC_BE:
+ m->m_pkthdr.prio = MBUF_TC_BE;
+ break;
+ case SO_TC_BK:
+ m->m_pkthdr.prio = MBUF_TC_BK;
+ break;
+ case SO_TC_VI:
+ m->m_pkthdr.prio = MBUF_TC_VI;
+ break;
+ case SO_TC_VO:
+ m->m_pkthdr.prio = MBUF_TC_VO;
+ break;
+ default:
+ break;
+ }
+ }
+ return;
+#endif /* PKT_PRIORITY */
+}
break;
}
+#if PKT_PRIORITY
+ case SO_TRAFFIC_CLASS: {
+ error = sooptcopyin(sopt, &optval, sizeof (optval),
+ sizeof (optval));
+ if (error)
+ goto bad;
+ if (optval < SO_TC_BE || optval > SO_TC_VO) {
+ error = EINVAL;
+ goto bad;
+ }
+ so->so_traffic_class = optval;
+ }
+#endif /* PKT_PRIORITY */
+
default:
error = ENOPROTOOPT;
break;
error = sooptcopyout(sopt, &sonpx, sizeof(struct so_np_extensions));
break;
}
+#if PKT_PRIORITY
+ case SO_TRAFFIC_CLASS:
+ optval = so->so_traffic_class;
+ goto integer;
+#endif /* PKT_PRIORITY */
+
default:
error = ENOPROTOOPT;
break;
/*
- * Copyright (c) 1998-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
so->so_traffic_mgt_flags = head->so_traffic_mgt_flags &
(TRAFFIC_MGT_SO_BACKGROUND | TRAFFIC_MGT_SO_BG_REGULATE);
so->so_background_thread = head->so_background_thread;
+#if PKT_PRIORITY
+ so->so_traffic_class = head->so_traffic_class;
+#endif /* PKT_PRIORITY */
if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat)) {
sflt_termsock(so);
return (so->so_traffic_mgt_flags & TRAFFIC_MGT_SO_BACKGROUND);
}
+#if PKT_PRIORITY
+#define _MIN_NXT_CMSGHDR_PTR(cmsg) \
+ ((char *)(cmsg) + \
+ __DARWIN_ALIGN32((__uint32_t)(cmsg)->cmsg_len) + \
+ __DARWIN_ALIGN32(sizeof(struct cmsghdr)))
+
+#define M_FIRST_CMSGHDR(m) \
+ ((char *)(m) != (char *)0L && (size_t)(m)->m_len >= sizeof(struct cmsghdr) && \
+ (socklen_t)(m)->m_len >= __DARWIN_ALIGN32(((struct cmsghdr *)(m)->m_data)->cmsg_len) ?\
+ (struct cmsghdr *)(m)->m_data : \
+ (struct cmsghdr *)0L)
+
+#define M_NXT_CMSGHDR(m, cmsg) \
+ ((char *)(cmsg) == (char *)0L ? M_FIRST_CMSGHDR(m) : \
+ _MIN_NXT_CMSGHDR_PTR(cmsg) > ((char *)(m)->m_data) + (m)->m_len || \
+ _MIN_NXT_CMSGHDR_PTR(cmsg) < (char *)(m)->m_data ? \
+ (struct cmsghdr *)0L /* NULL */ : \
+ (struct cmsghdr *)((unsigned char *)(cmsg) + \
+ __DARWIN_ALIGN32((__uint32_t)(cmsg)->cmsg_len)))
+#endif /* PKT_PRIORITY */
+
+__private_extern__ int
+mbuf_traffic_class_from_control(struct mbuf *control)
+{
+#if !PKT_PRIORITY
+#pragma unused(control)
+ return MBUF_TC_NONE;
+#else /* PKT_PRIORITY */
+ struct cmsghdr *cm;
+
+ for (cm = M_FIRST_CMSGHDR(control); cm; cm = M_NXT_CMSGHDR(control, cm)) {
+ int tc;
+
+ if (cm->cmsg_len < sizeof(struct cmsghdr))
+ break;
+
+ if (cm->cmsg_level != SOL_SOCKET || cm->cmsg_type != SO_TRAFFIC_CLASS)
+ continue;
+ if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
+ continue;
+
+ tc = *(int *)CMSG_DATA(cm);
+
+ switch (tc) {
+ case SO_TC_BE:
+ return MBUF_TC_BE;
+ case SO_TC_BK:
+ return MBUF_TC_BK;
+ case SO_TC_VI:
+ return MBUF_TC_VI;
+ case SO_TC_VO:
+ return MBUF_TC_VO;
+ default:
+ break;
+ }
+ }
+
+ return MBUF_TC_NONE;
+#endif /* PKT_PRIORITY */
+}
+
/*
* Here is the definition of some of the basic objects in the kern.ipc
* branch of the MIB.
/*
- * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
{
thread_t thread = THREAD_NULL;
-#if PKT_PRIORITY
- /*
- * The following fields must be 32-bit aligned for atomic operations.
- */
- IF_DATA_REQUIRE_ALIGNED_32(ifi_obgpackets);
- IF_DATA_REQUIRE_ALIGNED_32(ifi_obgbytes)
-
- IFNET_IF_DATA_REQUIRE_ALIGNED_32(ifi_obgpackets);
- IFNET_IF_DATA_REQUIRE_ALIGNED_32(ifi_obgbytes)
-#endif /* PKT_PRIORITY */
-
PE_parse_boot_argn("net_affinity", &net_affinity, sizeof (net_affinity));
#if IFNET_ROUTE_REFCNT
PE_parse_boot_argn("net_rtref", &net_rtref, sizeof (net_rtref));
locked = 1;
dlil_read_begin();
}
+
+#if PKT_PRIORITY
+ switch (m->m_pkthdr.prio) {
+ case MBUF_TC_BK:
+ ifp->if_tc.ifi_ibkpackets++;
+ ifp->if_tc.ifi_ibkbytes += m->m_pkthdr.len;
+ break;
+ case MBUF_TC_VI:
+ ifp->if_tc.ifi_ivipackets++;
+ ifp->if_tc.ifi_ivibytes += m->m_pkthdr.len;
+ break;
+ case MBUF_TC_VO:
+ ifp->if_tc.ifi_ivopackets++;
+ ifp->if_tc.ifi_ivobytes += m->m_pkthdr.len;
+ break;
+ default:
+ break;
+ }
+#endif PKT_PRIORITY
+
/* find which protocol family this packet is for */
error = (*ifp->if_demux)(ifp, m, frame_header,
&protocol_family);
}
#endif
+static void
+if_inc_traffic_class_out(ifnet_t ifp, mbuf_t m)
+{
+#if !PKT_PRIORITY
+#pragma unused(ifp)
+#pragma unused(m)
+ return;
+#else
+ if (!(m->m_flags & M_PKTHDR))
+ return;
+
+ switch (m->m_pkthdr.prio) {
+ case MBUF_TC_BK:
+ ifp->if_tc.ifi_obkpackets++;
+ ifp->if_tc.ifi_obkbytes += m->m_pkthdr.len;
+ break;
+ case MBUF_TC_VI:
+ ifp->if_tc.ifi_ovipackets++;
+ ifp->if_tc.ifi_ovibytes += m->m_pkthdr.len;
+ break;
+ case MBUF_TC_VO:
+ ifp->if_tc.ifi_ovopackets++;
+ ifp->if_tc.ifi_ovobytes += m->m_pkthdr.len;
+ break;
+ default:
+ break;
+ }
+#endif PKT_PRIORITY
+}
+
#if 0
int
dlil_output_list(
}
else {
KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT | DBG_FUNC_START, 0,0,0,0,0);
-#if PKT_PRIORITY
- if (mbuf_get_priority(m) == MBUF_PRIORITY_BACKGROUND) {
- atomic_add_32(&ifp->if_obgpackets, 1);
- atomic_add_32(&ifp->if_obgbytes,
- m->m_pkthdr.len);
- }
-#endif /* PKT_PRIORITY */
+
+ if_inc_traffic_class_out(ifp, m);
+
retval = ifp->if_output(ifp, m);
if (retval && dlil_verbose) {
printf("dlil_output: output error on %s%d retval = %d\n",
if (send_head) {
KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT | DBG_FUNC_START, 0,0,0,0,0);
-#if PKT_PRIORITY
- if (mbuf_get_priority(send_head) == MBUF_PRIORITY_BACKGROUND) {
- atomic_add_32(&ifp->if_obgpackets, 1);
- atomic_add_32(&ifp->if_obgbytes,
- send_head->m_pkthdr.len);
- }
-#endif /* PKT_PRIORITY */
+
+ if_inc_traffic_class_out(ifp, send_head);
+
retval = ifp->if_output(ifp, send_head);
if (retval && dlil_verbose) {
printf("dlil_output: output error on %s%d retval = %d\n",
/*
- * Copyright (c) 2000-2009 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <net/if.h>
#include <net/if_mib.h>
+#include <net/if_var.h>
#if NETMIBS
ifmd.ifmd_snd_len = ifp->if_snd.ifq_len;
ifmd.ifmd_snd_maxlen = ifp->if_snd.ifq_maxlen;
ifmd.ifmd_snd_drops = ifp->if_snd.ifq_drops;
-#if PKT_PRIORITY
- /* stuff these into unused fields for now */
- ifmd.ifmd_filler[0] = ifp->if_obgpackets;
- ifmd.ifmd_filler[1] = ifp->if_obgbytes;
-#endif /* PKT_PRIORITY */
}
error = SYSCTL_OUT(req, &ifmd, sizeof ifmd);
if (error || !req->newptr)
break;
#endif /* IF_MIB_WR */
break;
+
+#if PKT_PRIORITY
+ case IFDATA_SUPPLEMENTAL:
+ error = SYSCTL_OUT(req, &ifp->if_tc, sizeof(struct if_traffic_class));
+ break;
+#endif /* PKT_PRIORITY */
}
return error;
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
struct if_data64 ifmd_data; /* generic information and statistics */
};
+#ifdef PRIVATE
+struct ifmibdata_supplemental {
+ struct if_traffic_class ifmd_traffic_class;
+};
+#endif /* PRIVATE */
+
/*
* sysctl MIB tags at the net.link.generic level
*/
#define IFDATA_LINKSPECIFIC 2 /* specific to the type of interface */
#define IFDATA_ADDRS 3 /* addresses assigned to interface */
#define IFDATA_MULTIADDRS 4 /* multicast addresses assigned to interface */
+#ifdef PRIVATE
+#define IFDATA_SUPPLEMENTAL 5 /* supplemental link specific stats */
+#endif /* PRIVATE */
/*
* MIB tags at the net.link.generic.system level
#pragma pack()
#ifdef PRIVATE
+struct if_traffic_class {
+ u_int64_t ifi_ibkpackets; /* TC_BK packets received on interface */
+ u_int64_t ifi_ibkbytes; /* TC_BK bytes received on interface */
+ u_int64_t ifi_obkpackets; /* TC_BK packet sent on interface */
+ u_int64_t ifi_obkbytes; /* TC_BK bytes sent on interface */
+ u_int64_t ifi_ivipackets; /* TC_VI packets received on interface */
+ u_int64_t ifi_ivibytes; /* TC_VI bytes received on interface */
+ u_int64_t ifi_ovipackets; /* TC_VI packets sent on interface */
+ u_int64_t ifi_ovibytes; /* TC_VI bytes sent on interface */
+ u_int64_t ifi_ivopackets; /* TC_VO packets received on interface */
+ u_int64_t ifi_ivobytes; /* TC_VO bytes received on interface */
+ u_int64_t ifi_ovopackets; /* TC_VO packets sent on interface */
+ u_int64_t ifi_ovobytes; /* TC_VO bytes sent on interface */
+};
+
/*
* Internal storage of if_data. This is bound to change. Various places in the
* stack will translate this data structure in to the externally visible
u_int64_t ifi_omcasts; /* packets sent via multicast */
u_int64_t ifi_iqdrops; /* dropped on input, this interface */
u_int64_t ifi_noproto; /* destined for unsupported protocol */
-#if PKT_PRIORITY
- u_int32_t ifi_obgpackets; /* bg packets sent on interface */
- u_int32_t ifi_obgbytes; /* total number of bg octets sent */
-#endif /* PKT_PRIORITY */
u_int32_t ifi_recvtiming; /* usec spent receiving when timing */
u_int32_t ifi_xmittiming; /* usec spent xmitting when timing */
#define IF_LASTCHANGEUPTIME 1 /* lastchange: 1-uptime 0-calendar time */
#define if_omcasts if_data.ifi_omcasts
#define if_iqdrops if_data.ifi_iqdrops
#define if_noproto if_data.ifi_noproto
-#if PKT_PRIORITY
-#define if_obgpackets if_data.ifi_obgpackets
-#define if_obgbytes if_data.ifi_obgbytes
-#endif /* PKT_PRIORITY */
#define if_lastchange if_data.ifi_lastchange
#define if_recvquota if_data.ifi_recvquota
#define if_xmitquota if_data.ifi_xmitquota
u_int32_t if_idle_flags; /* idle flags */
u_int32_t if_route_refcnt; /* idle: route ref count */
#endif /* IFNET_ROUTE_REFCNT */
+#if PKT_PRIORITY
+ struct if_traffic_class if_tc __attribute__((aligned(8)));
+#endif /* PKT_PRIORITY */
};
#ifndef __APPLE__
/*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
struct ip *const ip = mtod(m, struct ip *);
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
int error = 0;
+#if PKT_PRIORITY
+ mbuf_traffic_class_t mtc = MBUF_TC_NONE;
+#endif /* PKT_PRIORITY */
- if (control)
- m_freem(control); /* XXX */
+ if (control != NULL) {
+#if PKT_PRIORITY
+ mtc = mbuf_traffic_class_from_control(control);
+#endif /* PKT_PRIORITY */
+ m_freem(control); /* XXX */
+ }
/* Loopback avoidance and state recovery */
if (sin) {
struct m_tag *mtag;
inp_route_copyout(inp, &ro);
#if PKT_PRIORITY
- if (soisbackground(so))
- m_prio_background(m);
+ set_traffic_class(m, so, mtc);
#endif /* PKT_PRIORITY */
socket_unlock(so, 0);
/*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
void rip_ctlinput(int, struct sockaddr *, void *);
void rip_init(void) __attribute__((section("__TEXT, initcode")));
void rip_input(struct mbuf *, int);
-int rip_output(struct mbuf *, struct socket *, u_int32_t);
+int rip_output(struct mbuf *, struct socket *, u_int32_t, struct mbuf *);
int rip_unlock(struct socket *, int, void *);
void ipip_input(struct mbuf *, int);
void rsvp_input(struct mbuf *, int);
/*
- * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* Tack on options user may have setup with control call.
*/
int
-rip_output(m, so, dst)
- register struct mbuf *m;
- struct socket *so;
- u_int32_t dst;
+rip_output(
+ struct mbuf *m,
+ struct socket *so,
+ u_int32_t dst,
+ struct mbuf *control)
{
register struct ip *ip;
register struct inpcb *inp = sotoinpcb(so);
int flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST;
struct ip_out_args ipoa;
int error = 0;
+#if PKT_PRIORITY
+ mbuf_traffic_class_t mtc = MBUF_TC_NONE;
+#endif /* PKT_PRIORITY */
+ if (control != NULL) {
+#if PKT_PRIORITY
+ mtc = mbuf_traffic_class_from_control(control);
+#endif /* PKT_PRIORITY */
+
+ m_freem(control);
+ }
/* If socket was bound to an ifindex, tell ip_output about it */
ipoa.ipoa_ifscope = (inp->inp_flags & INP_BOUND_IF) ?
inp->inp_boundif : IFSCOPE_NONE;
}
#if PKT_PRIORITY
- if (soisbackground(so))
- m_prio_background(m);
+ set_traffic_class(m, so, mtc);
#endif /* PKT_PRIORITY */
#if CONFIG_MACF_NET
}
dst = ((struct sockaddr_in *)nam)->sin_addr.s_addr;
}
- return rip_output(m, so, dst);
+ return rip_output(m, so, dst, control);
}
/* note: rip_unlock is called from different protos instead of the generic socket_unlock,
/*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
}
#endif /*IPSEC*/
m->m_pkthdr.socket_id = socket_id;
+
#if PKT_PRIORITY
- if (soisbackground(so))
- m_prio_background(m);
+ set_traffic_class(m, so, MBUF_TC_NONE);
#endif /* PKT_PRIORITY */
error = ip6_output(m,
inp6_pktopts,
lost = 0;
m->m_pkthdr.socket_id = socket_id;
m->m_nextpkt = NULL;
+#if PKT_PRIORITY
+ set_traffic_class(m, so, MBUF_TC_NONE);
+#endif /* PKT_PRIORITY */
tp->t_pktlist_sentlen += len;
tp->t_lastchain++;
if (tp->t_pktlist_head != NULL) {
struct inpcb *inp = tp->t_inpcb;
struct ip_out_args ipoa;
struct route ro;
-#if PKT_PRIORITY
- boolean_t bg = FALSE;
-#endif /* PKT_PRIORITY */
+#if CONFIG_OUT_IF
+ unsigned int outif;
+#endif /* CONFIG_OUT_IF */
/* If socket was bound to an ifindex, tell ip_output about it */
ipoa.ipoa_ifscope = (inp->inp_flags & INP_BOUND_IF) ?
/* Copy the cached route and take an extra reference */
inp_route_copyout(inp, &ro);
-#if PKT_PRIORITY
- bg = soisbackground(so);
-#endif /* PKT_PRIORITY */
-
/*
* Data sent (as far as we can tell).
* If this advertises a larger window than any other segment,
*/
cnt = 0;
}
-#if PKT_PRIORITY
- if (bg)
- m_prio_background(pkt);
-#endif /* PKT_PRIORITY */
+
error = ip_output_list(pkt, cnt, opt, &ro, flags, 0, &ipoa);
if (chain || error) {
/*
/*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
}
#endif
#if PKT_PRIORITY
- if (tp != NULL && soisbackground(tp->t_inpcb->inp_socket))
- m_prio_background(m);
+ if (tp != NULL)
+ set_traffic_class(m, tp->t_inpcb->inp_socket, MBUF_TC_NONE);
#endif /* PKT_PRIORITY */
#if INET6
if (isipv6) {
/*
- * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
struct ip_moptions *mopts;
struct route ro;
struct ip_out_args ipoa;
+#if PKT_PRIORITY
+ mbuf_traffic_class_t mtc = MBUF_TC_NONE;
+#endif /* PKT_PRIORITY */
KERNEL_DEBUG(DBG_FNC_UDP_OUTPUT | DBG_FUNC_START, 0,0,0,0,0);
- if (control)
- m_freem(control); /* XXX */
-
+ if (control != NULL) {
+#if PKT_PRIORITY
+ mtc = mbuf_traffic_class_from_control(control);
+#endif /* PKT_PRIORITY */
+ m_freem(control);
+ }
KERNEL_DEBUG(DBG_LAYER_OUT_BEG, inp->inp_fport, inp->inp_lport,
inp->inp_laddr.s_addr, inp->inp_faddr.s_addr,
(htons((u_short)len + sizeof (struct udphdr))));
inp_route_copyout(inp, &ro);
#if PKT_PRIORITY
- if (soisbackground(so))
- m_prio_background(m);
+ set_traffic_class(m, so, mtc);
#endif /* PKT_PRIORITY */
socket_unlock(so, 0);
ip6 = mtod(m, struct ip6_hdr *);
inject_filter_ref = ipf_get_inject_filter(m);
+ finaldst = ip6->ip6_dst;
#define MAKE_EXTHDR(hp, mp) \
do { \
/*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
struct ifnet *oifp = NULL;
int type = 0, code = 0; /* for ICMPv6 output statistics only */
int priv = 0;
+#if PKT_PRIORITY
+ mbuf_traffic_class_t mtc = MBUF_TC_NONE;
+#endif /* PKT_PRIORITY */
in6p = sotoin6pcb(so);
priv = 1;
dst = &dstsock->sin6_addr;
if (control) {
+#if PKT_PRIORITY
+ mtc = mbuf_traffic_class_from_control(control);
+#endif /* PKT_PRIORITY */
+
if ((error = ip6_setpktoptions(control, &opt, priv, 0)) != 0)
goto bad;
optp = &opt;
}
#if PKT_PRIORITY
- if (soisbackground(so))
- m_prio_background(m);
+ set_traffic_class(m, so, mtc);
#endif /* PKT_PRIORITY */
error = ip6_output(m, optp, &in6p->in6p_route, 0,
/*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
int flags;
struct sockaddr_in6 tmp;
struct in6_addr storage;
+#if PKT_PRIORITY
+ mbuf_traffic_class_t mtc = MBUF_TC_NONE;
+#endif /* PKT_PRIORITY */
priv = (proc_suser(p) == 0);
if (control) {
+#if PKT_PRIORITY
+ mtc = mbuf_traffic_class_from_control(control);
+#endif /* PKT_PRIORITY */
+
if ((error = ip6_setpktoptions(control, &opt, priv, 0)) != 0)
goto release;
in6p->in6p_outputopts = &opt;
}
#endif /*IPSEC*/
m->m_pkthdr.socket_id = get_socket_id(in6p->in6p_socket);
+
#if PKT_PRIORITY
- if (soisbackground(in6p->in6p_socket))
- m_prio_background(m);
+ set_traffic_class(m, in6p->in6p_socket, mtc);
#endif /* PKT_PRIORITY */
error = ip6_output(m, in6p->in6p_outputopts, &in6p->in6p_route,
flags, in6p->in6p_moptions, NULL, 0);
/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
@result The priority value of the packet.
*/
extern mbuf_priority_t mbuf_get_priority(mbuf_t mbuf);
+
+/*
+ @enum mbuf_traffic_class_t
+ @abstract Traffic class of a packet
+ @discussion Property that represent the category of traffic of a packet.
+ This information may be used by the driver and at the link level.
+ @constant MBUF_TC_BE Best effort, normal class.
+ @constant MBUF_TC_BK Background, low priority or bulk traffic.
+ @constant MBUF_TC_VI Interactive video, constant bit rate, low latency.
+ @constant MBUF_TC_VO Interactive voice, constant bit rate, lowest latency.
+*/
+typedef enum {
+#ifdef XNU_KERNEL_PRIVATE
+ MBUF_TC_NONE = -1,
+#endif
+ MBUF_TC_BE = 0,
+ MBUF_TC_BK = 1,
+ MBUF_TC_VI = 2,
+ MBUF_TC_VO = 3
+} mbuf_traffic_class_t;
+
+/*
+ @function mbuf_get_traffic_class
+ @discussion Get the traffic class of an mbuf packet
+ @param mbuf The mbuf to get the traffic class of.
+ @result The traffic class
+*/
+extern mbuf_traffic_class_t mbuf_get_traffic_class(mbuf_t mbuf);
+
+/*
+ @function mbuf_set_traffic_class
+ @discussion Set the traffic class of an mbuf packet.
+ @param mbuf The mbuf to set the traffic class on.
+ @ac The traffic class
+ @result 0 on success, EINVAL if bad paramater is passed
+*/
+extern errno_t mbuf_set_traffic_class(mbuf_t mbuf, mbuf_traffic_class_t tc);
#endif /* KERNEL_PRIVATE */
/* IF_QUEUE interaction */
/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
/*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#endif
#ifdef PRIVATE
#define SO_EXECPATH 0x1085 /* Application Firewall Socket option */
+#define SO_TRAFFIC_CLASS 0x1086 /* Traffic class */
+#define SO_TC_BE 0 /* Best effort, normal */
+#define SO_TC_BK 1 /* Background, low priority or bulk traffic */
+#define SO_TC_VI 2 /* Interactive video, constant bit rate, low latency */
+#define SO_TC_VO 3 /* Interactive voice, constant bit rate, lowest latency */
#endif
#define SO_LABEL 0x1010 /* socket's MAC label */
#define SO_PEERLABEL 0x1011 /* socket's peer MAC label */
/*
- * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
struct label *so_label; /* MAC label for socket */
struct label *so_peerlabel; /* cached MAC label for socket peer */
thread_t so_background_thread; /* thread that marked this socket background */
+#if PKT_PRIORITY
+ int so_traffic_class;
+#endif /* PKT_PRIORITY */
};
#endif /* KERNEL_PRIVATE */
extern void sofreelastref(struct socket *, int);
extern int sogetaddr_locked(struct socket *, struct sockaddr **, int);
extern const char *solockhistory_nr(struct socket *);
+extern void set_traffic_class(struct mbuf *, struct socket *, int);
+extern int mbuf_traffic_class_from_control(struct mbuf *);
/*
* XXX; prepare mbuf for (__FreeBSD__ < 3) routines.
if (vnode_isshadow(vp)) {
vnode_relenamedstream(pvp, vp, ctx);
}
-
+
+ /*
+ * Because vclean calls VNOP_INACTIVE prior to calling vnode_relenamedstream, we may not have
+ * torn down and/or deleted the shadow file yet. On HFS, if the shadow file is sufficiently large
+ * and occupies a large number of extents, the deletion will be deferred until VNOP_INACTIVE
+ * and the file treated like an open-unlinked. To rectify this, call VNOP_INACTIVE again
+ * explicitly to force its removal.
+ */
+ if (vnode_isshadow(vp)) {
+ VNOP_INACTIVE(vp, ctx);
+ }
+
/*
* No more streams associated with the parent. We
* have a ref on it, so its identity is stable.
-10.6.0
+10.7.0
# The first line of this file contains the master version number for the kernel.
# All other instances of the kernel version in xnu are derived from this file.
_m_trailingspace:_mbuf_trailingspace
_mac_proc_set_enforce
_mbuf_get_priority
+_mbuf_get_traffic_class
+_mbuf_set_traffic_class
_mcl_to_paddr
_mountroot_post_hook
_net_add_domain
thread->machine.specFlags |= CopyIOActive;
#endif /* CONFIG_DTRACE */
- if ((nbytes && (user_addr + nbytes <= user_addr)) || ((user_addr + nbytes) > vm_map_max(thread->map))) {
+ if ((nbytes && (user_addr + nbytes <= user_addr)) ||
+ (user_addr < vm_map_min(thread->map)) ||
+ (user_addr + nbytes > vm_map_max(thread->map))) {
error = EFAULT;
goto done;
}
volatile uint64_t debugger_exit_time;
#if MACH_KDP
+extern int kdp_snapshot;
static struct _kdp_xcpu_call_func {
kdp_x86_xcpu_func_t func;
void *arg0, *arg1;
* access through the debugger.
*/
sync_iss_to_iks(regs);
+ if (pmsafe_debug && !kdp_snapshot)
+ pmSafeMode(¤t_cpu_datap()->lcpu, PM_SAFE_FL_SAFE);
mp_kdp_wait(TRUE, FALSE);
+ if (pmsafe_debug && !kdp_snapshot)
+ pmSafeMode(¤t_cpu_datap()->lcpu, PM_SAFE_FL_NORMAL);
} else
#endif /* MACH_KDP */
if (i_bit(MP_TLB_FLUSH, my_word)) {
}
#if MACH_KDP
+ if (pmsafe_debug && !kdp_snapshot)
+ pmSafeMode(¤t_cpu_datap()->lcpu, PM_SAFE_FL_SAFE);
mp_kdp_wait(FALSE, pmap_tlb_flush_timeout);
+ if (pmsafe_debug && !kdp_snapshot)
+ pmSafeMode(¤t_cpu_datap()->lcpu, PM_SAFE_FL_NORMAL);
#endif
NMExit:
return 1;
mp_kdp_state = ml_set_interrupts_enabled(FALSE);
simple_lock(&mp_kdp_lock);
debugger_entry_time = mach_absolute_time();
- if (pmsafe_debug)
+ if (pmsafe_debug && !kdp_snapshot)
pmSafeMode(¤t_cpu_datap()->lcpu, PM_SAFE_FL_SAFE);
while (mp_kdp_trap) {
mca_check_save();
#endif
- if (pmsafe_debug)
- pmSafeMode(¤t_cpu_datap()->lcpu, PM_SAFE_FL_SAFE);
-
atomic_incl((volatile long *)&mp_kdp_ncpus, 1);
while (mp_kdp_trap || (isNMI == TRUE)) {
/*
cpu_pause();
}
- if (pmsafe_debug)
- pmSafeMode(¤t_cpu_datap()->lcpu, PM_SAFE_FL_NORMAL);
-
atomic_decl((volatile long *)&mp_kdp_ncpus, 1);
DBG("mp_kdp_wait() done\n");
}
cpu_pause();
}
- if (pmsafe_debug)
+ if (pmsafe_debug && !kdp_snapshot)
pmSafeMode(¤t_cpu_datap()->lcpu, PM_SAFE_FL_NORMAL);
DBG("mp_kdp_exit() done\n");
kprintf("user_trap(0x%08x) type=%d vaddr=0x%016llx\n",
saved_state, type, vaddr);
#endif
- myast = ast_pending();
perfCallback fn = perfASTHook;
if (fn) {
+ myast = ast_pending();
if (*myast & AST_CHUD_ALL) {
fn(type, saved_state, 0, 0);
}
- } else {
- *myast &= ~AST_CHUD_ALL;
}
/* Is there a hook? */
}
ldt_count = end_sel - begin_sel;
-
+ /* XXX allocation under task lock */
new_ldt = (user_ldt_t)kalloc(sizeof(struct user_ldt) + (ldt_count * sizeof(struct real_descriptor)));
if (new_ldt == NULL) {
task_unlock(task);
* Install new descriptors.
*/
if (descs != 0) {
+ /* XXX copyin under task lock */
err = copyin(descs, (char *)&new_ldt->ldt[start_sel - begin_sel],
num_sels * sizeof(struct real_descriptor));
if (err != 0)
/*
* Validate descriptors.
- * Only allow descriptors with user priviledges.
+ * Only allow descriptors with user privileges.
*/
for (i = 0, dp = (struct real_descriptor *) &new_ldt->ldt[start_sel - begin_sel];
i < num_sels;
switch (dp->access & ~ACC_A) {
case 0:
case ACC_P:
- /* valid empty descriptor */
+ /* valid empty descriptor, clear Present preemptively */
+ dp->access &= ~ACC_P;
break;
case ACC_P | ACC_PL_U | ACC_DATA:
case ACC_P | ACC_PL_U | ACC_DATA_W:
case ACC_P | ACC_PL_U | ACC_CODE_R:
case ACC_P | ACC_PL_U | ACC_CODE_C:
case ACC_P | ACC_PL_U | ACC_CODE_CR:
- case ACC_P | ACC_PL_U | ACC_CALL_GATE_16:
- case ACC_P | ACC_PL_U | ACC_CALL_GATE:
break;
default:
task_unlock(task);
}
/* Populate the thread snapshot header */
tsnap = (thread_snapshot_t) tracepos;
- tsnap->thread_id = (uint64_t) (uintptr_t)thread;
+ tsnap->thread_id = thread_tid(thread);
tsnap->state = thread->state;
tsnap->wait_event = thread->wait_event;
tsnap->continuation = (uint64_t) (uintptr_t) thread->continuation;
}
dst_page->precious = (cntrl_flags & UPL_PRECIOUS) ? TRUE : FALSE;
}
+ if (dst_page->busy)
+ upl->flags |= UPL_HAS_BUSY;
+
if (dst_page->phys_page > upl->highest_page)
upl->highest_page = dst_page->phys_page;
if (user_page_list) {
goto process_upl_to_enter;
vector_upl_get_iostate(vector_upl, upl, &subupl_offset, &subupl_size);
*dst_addr = (vm_map_offset_t)(vector_upl_dst_addr + (vm_map_offset_t)subupl_offset);
+ } else {
+ /*
+ * check to see if already mapped
+ */
+ if (UPL_PAGE_LIST_MAPPED & upl->flags) {
+ upl_unlock(upl);
+ return KERN_FAILURE;
+ }
}
+ if ((!(upl->flags & UPL_SHADOWED)) &&
+ ((upl->flags & UPL_HAS_BUSY) ||
+ !((upl->flags & (UPL_DEVICE_MEMORY | UPL_IO_WIRE)) || (upl->map_object->phys_contiguous)))) {
- /*
- * check to see if already mapped
- */
- if (UPL_PAGE_LIST_MAPPED & upl->flags) {
- upl_unlock(upl);
- return KERN_FAILURE;
- }
-
- if ((!(upl->flags & UPL_SHADOWED)) && !((upl->flags & (UPL_DEVICE_MEMORY | UPL_IO_WIRE)) ||
- (upl->map_object->phys_contiguous))) {
vm_object_t object;
vm_page_t alias_page;
vm_object_offset_t new_offset;
}
vm_object_unlock(upl->map_object);
}
- if ((upl->flags & (UPL_DEVICE_MEMORY | UPL_IO_WIRE)) || upl->map_object->phys_contiguous)
- offset = upl->offset - upl->map_object->paging_offset;
- else
+ if (upl->flags & UPL_SHADOWED)
offset = 0;
+ else
+ offset = upl->offset - upl->map_object->paging_offset;
size = upl->size;
vm_object_reference(upl->map_object);
kr = vm_map_enter(map, dst_addr, (vm_map_size_t)size, (vm_map_offset_t) 0,
VM_FLAGS_ANYWHERE, upl->map_object, offset, FALSE,
VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
+
+ if (kr != KERN_SUCCESS) {
+ upl_unlock(upl);
+ return(kr);
+ }
}
else {
kr = vm_map_enter(map, dst_addr, (vm_map_size_t)size, (vm_map_offset_t) 0,
if(kr)
panic("vm_map_enter failed for a Vector UPL\n");
}
-
- if (kr != KERN_SUCCESS) {
- upl_unlock(upl);
- return(kr);
- }
vm_object_lock(upl->map_object);
for (addr = *dst_addr; size > 0; size -= PAGE_SIZE, addr += PAGE_SIZE) {
upl->kaddr = (vm_offset_t) *dst_addr;
assert(upl->kaddr == *dst_addr);
- if(!isVectorUPL)
- upl_unlock(upl);
- else
+ if(isVectorUPL)
goto process_upl_to_enter;
+ upl_unlock(upl);
+
return KERN_SUCCESS;
}
}
if (upl->flags & UPL_IO_WIRE) {
- dwp->dw_mask |= DW_vm_page_unwire;
-
if (page_list)
page_list[entry].phys_addr = 0;
if (m->absent) {
if (flags & UPL_COMMIT_FREE_ABSENT)
dwp->dw_mask |= DW_vm_page_free;
- else
+ else {
m->absent = FALSE;
- }
+ dwp->dw_mask |= (DW_clear_busy | DW_PAGE_WAKEUP);
+ }
+ } else
+ dwp->dw_mask |= DW_vm_page_unwire;
+
goto commit_next_page;
}
/*
case VM_FAULT_SUCCESS:
- PAGE_WAKEUP_DONE(dst_page);
+ if ( !dst_page->absent) {
+ PAGE_WAKEUP_DONE(dst_page);
+ } else {
+ /*
+ * we only get back an absent page if we
+ * requested that it not be zero-filled
+ * because we are about to fill it via I/O
+ *
+ * absent pages should be left BUSY
+ * to prevent them from being faulted
+ * into an address space before we've
+ * had a chance to complete the I/O on
+ * them since they may contain info that
+ * shouldn't be seen by the faulting task
+ */
+ }
/*
* Release paging references and
* top-level placeholder page, if any.
refmod = pmap_disconnect(dst_page->phys_page);
else
refmod = 0;
- vm_page_copy(dst_page, low_page);
+
+ if ( !dst_page->absent)
+ vm_page_copy(dst_page, low_page);
low_page->reference = dst_page->reference;
low_page->dirty = dst_page->dirty;
+ low_page->absent = dst_page->absent;
if (refmod & VM_MEM_REFERENCED)
low_page->reference = TRUE;
* BUSY... we don't need a PAGE_WAKEUP_DONE
* here, because we've never dropped the object lock
*/
- dst_page->busy = FALSE;
+ if ( !dst_page->absent)
+ dst_page->busy = FALSE;
}
- dwp->dw_mask |= DW_vm_page_wire;
+ if ( !dst_page->busy)
+ dwp->dw_mask |= DW_vm_page_wire;
if (cntrl_flags & UPL_BLOCK_ACCESS) {
/*
if (!(cntrl_flags & UPL_COPYOUT_FROM))
dst_page->dirty = TRUE;
record_phys_addr:
+ if (dst_page->busy)
+ upl->flags |= UPL_HAS_BUSY;
+
pg_num = (unsigned int) ((dst_offset-offset)/PAGE_SIZE);
assert(pg_num == (dst_offset-offset)/PAGE_SIZE);
lite_list[pg_num>>5] |= 1 << (pg_num & 31);
dst_page = vm_page_lookup(object, offset);
if (dst_page == VM_PAGE_NULL)
- panic("vm_object_iopl_request: Wired pages missing. \n");
+ panic("vm_object_iopl_request: Wired page missing. \n");
/*
* if we've already processed this page in an earlier
* vm_page_wire on this page
*/
need_unwire = FALSE;
+
+ dw_index++;
+ dw_count--;
}
- dw_index++;
- dw_count--;
}
vm_page_lock_queues();
- if (need_unwire == TRUE) {
- boolean_t queueit;
+ if (dst_page->absent) {
+ vm_page_free(dst_page);
- queueit = (dst_page->absent) ? FALSE : TRUE;
+ need_unwire = FALSE;
+ } else {
+ if (need_unwire == TRUE)
+ vm_page_unwire(dst_page, TRUE);
- vm_page_unwire(dst_page, queueit);
- }
- if (dst_page->absent)
- vm_page_free(dst_page);
- else
PAGE_WAKEUP_DONE(dst_page);
-
+ }
vm_page_unlock_queues();
if (need_unwire == TRUE)
#define UPL_SHADOWED 0x1000
#define UPL_KERNEL_OBJECT 0x2000
#define UPL_VECTOR 0x4000
+#define UPL_HAS_BUSY 0x10000
/* flags for upl_create flags parameter */
#define UPL_CREATE_EXTERNAL 0