From ab86ba338a07a58a89f50cf7066a0f0e487ac0cc Mon Sep 17 00:00:00 2001 From: Apple Date: Tue, 20 Jan 2004 01:37:00 +0000 Subject: [PATCH] xnu-517.3.7.tar.gz --- bsd/conf/version.minor | 2 +- bsd/hfs/hfs_vfsops.c | 9 +- bsd/net/if.c | 185 +++++++++++------- bsd/netinet/in_pcb.c | 6 + bsd/netinet/ip_output.c | 9 +- bsd/netinet/tcp_output.c | 8 +- bsd/netinet/tcp_subr.c | 4 + bsd/netinet/tcp_timer.c | 4 + bsd/netinet6/in6_ifattach.c | 30 +-- bsd/netinet6/nd6.c | 2 +- bsd/nfs/nfs_bio.c | 12 +- bsd/nfs/nfs_lock.c | 4 +- bsd/nfs/nfs_subs.c | 10 +- bsd/nfs/nfs_vnops.c | 30 +-- config/System.kext/Info.plist | 8 +- .../PlugIns/AppleNMI.kext/Info.plist | 6 +- .../ApplePlatformFamily.kext/Info.plist | 6 +- .../PlugIns/BSDKernel.kext/Info.plist | 8 +- .../System.kext/PlugIns/IOKit.kext/Info.plist | 8 +- .../PlugIns/IONVRAMFamily.kext/Info.plist | 6 +- .../IOSystemManagement.kext/Info.plist | 6 +- .../PlugIns/Libkern.kext/Info.plist | 8 +- .../System.kext/PlugIns/Mach.kext/Info.plist | 8 +- iokit/KernelConfigTables.cpp | 18 +- iokit/conf/version.minor | 2 +- libkern/conf/version.minor | 2 +- libsa/conf/version.minor | 2 +- osfmk/conf/kernelversion.minor | 2 +- osfmk/conf/version.minor | 2 +- osfmk/ppc/cswtch.s | 4 + osfmk/ppc/genassym.c | 2 + osfmk/ppc/hw_exception.s | 2 +- osfmk/ppc/hw_lock.s | 75 ++++++- osfmk/ppc/hw_vm.s | 3 + osfmk/ppc/machine_routines.c | 21 ++ osfmk/ppc/machine_routines.h | 2 + osfmk/ppc/machine_routines_asm.s | 2 +- osfmk/ppc/pcb.c | 4 + osfmk/ppc/rtclock.c | 3 + osfmk/ppc/thread_act.h | 2 + osfmk/vm/vm_pageout.c | 32 ++- pexpert/conf/version.minor | 2 +- pexpert/ppc/pe_identify_machine.c | 4 - 43 files changed, 386 insertions(+), 179 deletions(-) diff --git a/bsd/conf/version.minor b/bsd/conf/version.minor index 573541ac9..0cfbf0888 100644 --- a/bsd/conf/version.minor +++ b/bsd/conf/version.minor @@ -1 +1 @@ -0 +2 diff --git a/bsd/hfs/hfs_vfsops.c b/bsd/hfs/hfs_vfsops.c index d05facee6..9c28709e7 100644 --- a/bsd/hfs/hfs_vfsops.c +++ b/bsd/hfs/hfs_vfsops.c @@ -1802,8 +1802,15 @@ loop: simple_unlock(&mntvnode_slock); error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p); if (error) { - if (error == ENOENT) + if (error == ENOENT) { + /* + * If vnode is being reclaimed, yield so + * that it can be removed from our list. + */ + if (UBCISVALID(vp)) + (void) tsleep((caddr_t)&lbolt, PINOD, "hfs_sync", 0); goto loop; + } simple_lock(&mntvnode_slock); continue; } diff --git a/bsd/net/if.c b/bsd/net/if.c index 312e293a3..d193b0e99 100644 --- a/bsd/net/if.c +++ b/bsd/net/if.c @@ -106,7 +106,7 @@ MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address"); MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address"); int ifqmaxlen = IFQ_MAXLEN; -struct ifnethead ifnet; /* depend on static init XXX */ +struct ifnethead ifnet = TAILQ_HEAD_INITIALIZER(ifnet); struct ifmultihead ifma_lostlist = LIST_HEAD_INITIALIZER(ifma_lostlist); #if INET6 @@ -124,10 +124,86 @@ extern void nd6_setmtu __P((struct ifnet *)); * parameters. */ -int if_index = 0; +int if_index; struct ifaddr **ifnet_addrs; -struct ifnet **ifindex2ifnet = NULL; +struct ifnet **ifindex2ifnet; +#define INITIAL_IF_INDEXLIM 8 + +/* + * Function: if_next_index + * Purpose: + * Return the next available interface index. + * Grow the ifnet_addrs[] and ifindex2ifnet[] arrays to accomodate the + * added entry when necessary. + * + * Note: + * ifnet_addrs[] is indexed by (if_index - 1), whereas + * ifindex2ifnet[] is indexed by ifp->if_index. That requires us to + * always allocate one extra element to hold ifindex2ifnet[0], which + * is unused. + */ +static int +if_next_index(void) +{ + static int if_indexlim = 0; + static int if_list_growing = 0; + int new_index; + + while (if_list_growing) { + /* wait until list is done growing */ + (void)tsleep((caddr_t)&ifnet_addrs, PZERO, "if_next_index", 0); + } + new_index = ++if_index; + if (if_index > if_indexlim) { + unsigned n; + int new_if_indexlim; + caddr_t new_ifnet_addrs; + caddr_t new_ifindex2ifnet; + caddr_t old_ifnet_addrs; + + /* mark list as growing */ + if_list_growing = 1; + + old_ifnet_addrs = (caddr_t)ifnet_addrs; + if (ifnet_addrs == NULL) { + new_if_indexlim = INITIAL_IF_INDEXLIM; + } else { + new_if_indexlim = if_indexlim << 1; + } + + /* allocate space for the larger arrays */ + n = (2 * new_if_indexlim + 1) * sizeof(caddr_t); + new_ifnet_addrs = _MALLOC(n, M_IFADDR, M_WAITOK); + new_ifindex2ifnet = new_ifnet_addrs + + new_if_indexlim * sizeof(caddr_t); + bzero(new_ifnet_addrs, n); + if (ifnet_addrs != NULL) { + /* copy the existing data */ + bcopy((caddr_t)ifnet_addrs, new_ifnet_addrs, + if_indexlim * sizeof(caddr_t)); + bcopy((caddr_t)ifindex2ifnet, + new_ifindex2ifnet, + (if_indexlim + 1) * sizeof(caddr_t)); + } + + /* switch to the new tables and size */ + ifnet_addrs = (struct ifaddr **)new_ifnet_addrs; + ifindex2ifnet = (struct ifnet **)new_ifindex2ifnet; + if_indexlim = new_if_indexlim; + + /* release the old data */ + if (old_ifnet_addrs != NULL) { + _FREE((caddr_t)old_ifnet_addrs, M_IFADDR); + } + + /* wake up others that might be blocked */ + if_list_growing = 0; + wakeup((caddr_t)&ifnet_addrs); + } + return (new_index); + +} /* * Attach an interface to the @@ -142,21 +218,10 @@ old_if_attach(ifp) char workbuf[64]; register struct sockaddr_dl *sdl; register struct ifaddr *ifa; - static int if_indexlim = 8; - static int inited; if (ifp->if_snd.ifq_maxlen == 0) ifp->if_snd.ifq_maxlen = ifqmaxlen; - if (!inited) { - TAILQ_INIT(&ifnet); - inited = 1; - } - - TAILQ_INSERT_TAIL(&ifnet, ifp, if_link); - /* if the interface is recycled, keep the index */ - if (!((ifp->if_eflags & IFEF_REUSE) && ifp->if_index)) - ifp->if_index = ++if_index; /* * XXX - * The old code would work if the interface passed a pre-existing @@ -168,64 +233,52 @@ old_if_attach(ifp) TAILQ_INIT(&ifp->if_prefixhead); LIST_INIT(&ifp->if_multiaddrs); getmicrotime(&ifp->if_lastchange); - if (ifnet_addrs == 0 || if_index >= if_indexlim) { - unsigned n = (if_indexlim <<= 1) * sizeof(ifa); - struct ifaddr **q = (struct ifaddr **) - _MALLOC(n, M_IFADDR, M_WAITOK); - bzero((caddr_t)q, n); - if (ifnet_addrs) { - bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2); - FREE((caddr_t)ifnet_addrs, M_IFADDR); - } - ifnet_addrs = (struct ifaddr **)q; - - /* grow ifindex2ifnet */ - n = if_indexlim * sizeof(struct ifaddr *); - q = (struct ifaddr **)_MALLOC(n, M_IFADDR, M_WAITOK); - bzero(q, n); - if (ifindex2ifnet) { - bcopy((caddr_t)ifindex2ifnet, q, n/2); - _FREE((caddr_t)ifindex2ifnet, M_IFADDR); - } - ifindex2ifnet = (struct ifnet **)q; - } - ifindex2ifnet[if_index] = ifp; + if ((ifp->if_eflags & IFEF_REUSE) == 0 || ifp->if_index == 0) { + /* allocate a new entry */ + ifp->if_index = if_next_index(); + ifindex2ifnet[ifp->if_index] = ifp; - /* - * create a Link Level name for this device - */ - namelen = snprintf(workbuf, sizeof(workbuf), - "%s%d", ifp->if_name, ifp->if_unit); + /* + * create a Link Level name for this device + */ + namelen = snprintf(workbuf, sizeof(workbuf), + "%s%d", ifp->if_name, ifp->if_unit); #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m)) - masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen; - socksize = masklen + ifp->if_addrlen; + masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen; + socksize = masklen + ifp->if_addrlen; #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1))) - if (socksize < sizeof(*sdl)) - socksize = sizeof(*sdl); - socksize = ROUNDUP(socksize); - ifasize = sizeof(*ifa) + 2 * socksize; - ifa = (struct ifaddr *) _MALLOC(ifasize, M_IFADDR, M_WAITOK); - if (ifa) { - bzero((caddr_t)ifa, ifasize); - sdl = (struct sockaddr_dl *)(ifa + 1); - sdl->sdl_len = socksize; - sdl->sdl_family = AF_LINK; - bcopy(workbuf, sdl->sdl_data, namelen); - sdl->sdl_nlen = namelen; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = ifp->if_type; - ifnet_addrs[if_index - 1] = ifa; - ifa->ifa_ifp = ifp; - ifa->ifa_rtrequest = link_rtrequest; - ifa->ifa_addr = (struct sockaddr *)sdl; - sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); - ifa->ifa_netmask = (struct sockaddr *)sdl; - sdl->sdl_len = masklen; - while (namelen != 0) - sdl->sdl_data[--namelen] = 0xff; + if (socksize < sizeof(*sdl)) + socksize = sizeof(*sdl); + socksize = ROUNDUP(socksize); + ifasize = sizeof(*ifa) + 2 * socksize; + ifa = (struct ifaddr *) _MALLOC(ifasize, M_IFADDR, M_WAITOK); + if (ifa) { + bzero((caddr_t)ifa, ifasize); + sdl = (struct sockaddr_dl *)(ifa + 1); + sdl->sdl_len = socksize; + sdl->sdl_family = AF_LINK; + bcopy(workbuf, sdl->sdl_data, namelen); + sdl->sdl_nlen = namelen; + sdl->sdl_index = ifp->if_index; + sdl->sdl_type = ifp->if_type; + ifnet_addrs[ifp->if_index - 1] = ifa; + ifa->ifa_ifp = ifp; + ifa->ifa_rtrequest = link_rtrequest; + ifa->ifa_addr = (struct sockaddr *)sdl; + sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); + ifa->ifa_netmask = (struct sockaddr *)sdl; + sdl->sdl_len = masklen; + while (namelen != 0) + sdl->sdl_data[--namelen] = 0xff; + } + } else { + ifa = ifnet_addrs[ifp->if_index - 1]; + } + if (ifa != NULL) { TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); } + TAILQ_INSERT_TAIL(&ifnet, ifp, if_link); } __private_extern__ int diff --git a/bsd/netinet/in_pcb.c b/bsd/netinet/in_pcb.c index ef52ab61f..3cb31d09f 100644 --- a/bsd/netinet/in_pcb.c +++ b/bsd/netinet/in_pcb.c @@ -592,6 +592,10 @@ in_pcbdetach(inp) struct inpcbinfo *ipi = inp->inp_pcbinfo; struct rtentry *rt = inp->inp_route.ro_rt; + + if (so->so_pcb == 0) /* we've been called twice, ignore */ + return; + #if IPSEC ipsec4_delete_pcbpolicy(inp); #endif /*IPSEC*/ @@ -820,6 +824,8 @@ in_rtchange(inp, errno) int errno; { if (inp->inp_route.ro_rt) { + if (ifa_foraddr(inp->inp_laddr.s_addr) == NULL) + return; /* we can't remove the route now. not sure if still ok to use src */ rtfree(inp->inp_route.ro_rt); inp->inp_route.ro_rt = 0; /* diff --git a/bsd/netinet/ip_output.c b/bsd/netinet/ip_output.c index 39daf8099..ec096591d 100644 --- a/bsd/netinet/ip_output.c +++ b/bsd/netinet/ip_output.c @@ -284,10 +284,15 @@ ip_output(m0, opt, ro, flags, imo) * cache with IPv6. */ + if (ro->ro_rt && (ro->ro_rt->generation_id != route_generation) && + ((flags & (IP_ROUTETOIF | IP_FORWARDING)) == 0) && (ip->ip_src.s_addr != INADDR_ANY) && + (ifa_foraddr(ip->ip_src.s_addr) == NULL)) { + error = EADDRNOTAVAIL; + goto bad; + } if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || dst->sin_family != AF_INET || - dst->sin_addr.s_addr != ip->ip_dst.s_addr || - ro->ro_rt->generation_id != route_generation) ) { + dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { rtfree(ro->ro_rt); ro->ro_rt = (struct rtentry *)0; } diff --git a/bsd/netinet/tcp_output.c b/bsd/netinet/tcp_output.c index 2f5bab119..d35b91673 100644 --- a/bsd/netinet/tcp_output.c +++ b/bsd/netinet/tcp_output.c @@ -231,8 +231,8 @@ again: * come back before the TCP connection times out). */ - if (tp->t_inpcb->inp_route.ro_rt != NULL && - (tp->t_inpcb->inp_route.ro_rt->generation_id != route_generation)) { + if ((tp->t_inpcb->inp_route.ro_rt != NULL && + (tp->t_inpcb->inp_route.ro_rt->generation_id != route_generation)) || (tp->t_inpcb->inp_route.ro_rt == NULL)) { /* check that the source address is still valid */ if (ifa_foraddr(tp->t_inpcb->inp_laddr.s_addr) == NULL) { if (tp->t_state >= TCPS_CLOSE_WAIT) { @@ -258,10 +258,6 @@ again: else return(0); /* silently ignore and keep data in socket */ } - else { /* Clear the cached route, will be reacquired later */ - rtfree(tp->t_inpcb->inp_route.ro_rt); - tp->t_inpcb->inp_route.ro_rt = (struct rtentry *)0; - } } } sendalot = 0; diff --git a/bsd/netinet/tcp_subr.c b/bsd/netinet/tcp_subr.c index 0ce5d476f..a09127e94 100644 --- a/bsd/netinet/tcp_subr.c +++ b/bsd/netinet/tcp_subr.c @@ -693,6 +693,9 @@ tcp_close(tp) register struct rtentry *rt; int dosavessthresh; + if ( inp->inp_ppcb == NULL) /* tcp_close was called previously, bail */ + return; + #ifndef __APPLE__ /* * Make sure that all of our timers are stopped before we @@ -712,6 +715,7 @@ tcp_close(tp) } } #endif + KERNEL_DEBUG(DBG_FNC_TCP_CLOSE | DBG_FUNC_START, tp,0,0,0,0); switch (tp->t_state) diff --git a/bsd/netinet/tcp_timer.c b/bsd/netinet/tcp_timer.c index 3d340b369..b7840d882 100644 --- a/bsd/netinet/tcp_timer.c +++ b/bsd/netinet/tcp_timer.c @@ -316,6 +316,10 @@ tpgone: #endif ipnxt = ip->inp_list.le_next; tp = intotcpcb(ip); + if (tp == NULL) { /* tp already closed, remove from list */ + LIST_REMOVE(ip, inp_list); + continue; + } if (tp->t_timer[TCPT_2MSL] >= N_TIME_WAIT_SLOTS) { tp->t_timer[TCPT_2MSL] -= N_TIME_WAIT_SLOTS; tp->t_rcvtime += N_TIME_WAIT_SLOTS; diff --git a/bsd/netinet6/in6_ifattach.c b/bsd/netinet6/in6_ifattach.c index 8fe4ea5eb..2b627e522 100644 --- a/bsd/netinet6/in6_ifattach.c +++ b/bsd/netinet6/in6_ifattach.c @@ -1035,6 +1035,8 @@ in6_tmpaddrtimer_funneled(void *ignored_arg) #endif } +extern size_t nd_ifinfo_indexlim; +extern int ip6_use_tempaddr; void in6_tmpaddrtimer(ignored_arg) void *ignored_arg; @@ -1048,19 +1050,23 @@ in6_tmpaddrtimer(ignored_arg) (ip6_temp_preferred_lifetime - ip6_desync_factor - ip6_temp_regen_advance) * hz); - bzero(nullbuf, sizeof(nullbuf)); - for (i = 1; i < if_index + 1; i++) { - ndi = &nd_ifinfo[i]; - if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) { - /* - * We've been generating a random ID on this interface. - * Create a new one. - */ - (void)generate_tmp_ifid(ndi->randomseed0, - ndi->randomseed1, - ndi->randomid); + if (ip6_use_tempaddr) { + + bzero(nullbuf, sizeof(nullbuf)); + for (i = 1; i < nd_ifinfo_indexlim + 1; i++) { + ndi = &nd_ifinfo[i]; + if (ndi->flags != ND6_IFF_PERFORMNUD) + continue; + if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) { + /* + * We've been generating a random ID on this interface. + * Create a new one. + */ + (void)generate_tmp_ifid(ndi->randomseed0, + ndi->randomseed1, + ndi->randomid); + } } } - splx(s); } diff --git a/bsd/netinet6/nd6.c b/bsd/netinet6/nd6.c index ffa6af8ec..2e9ac9683 100644 --- a/bsd/netinet6/nd6.c +++ b/bsd/netinet6/nd6.c @@ -102,7 +102,7 @@ int nd6_debug = 0; static int nd6_inuse, nd6_allocated; struct llinfo_nd6 llinfo_nd6 = {&llinfo_nd6, &llinfo_nd6}; -static size_t nd_ifinfo_indexlim = 8; +size_t nd_ifinfo_indexlim = 8; struct nd_ifinfo *nd_ifinfo = NULL; struct nd_drhead nd_defrouter; struct nd_prhead nd_prefix = { 0 }; diff --git a/bsd/nfs/nfs_bio.c b/bsd/nfs/nfs_bio.c index 1b6b078c5..3e67a2ac9 100644 --- a/bsd/nfs/nfs_bio.c +++ b/bsd/nfs/nfs_bio.c @@ -1015,9 +1015,9 @@ nfs_bioread(vp, uio, ioflag, cred, getpages) * Then force a getattr rpc to ensure that you have up to date * attributes. * NB: This implies that cache data can be read when up to - * NFS_MAXATTRTIMEO seconds out of date. If you find that you need current - * attributes this could be forced by setting n_attrstamp to 0 before - * the VOP_GETATTR() call. + * NFS_MAXATTRTIMEO seconds out of date. If you find that you need + * current attributes this could be forced by setting n_xid to 0 + * before the VOP_GETATTR() call. */ if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) { if (np->n_flag & NMODIFIED) { @@ -1031,7 +1031,7 @@ nfs_bioread(vp, uio, ioflag, cred, getpages) return (error); } } - np->n_attrstamp = 0; + np->n_xid = 0; error = VOP_GETATTR(vp, &vattr, cred, p); if (error) { FSDBG_BOT(514, vp, 0xd1e0004, 0, error); @@ -1536,7 +1536,7 @@ nfs_write(ap) (void)nfs_fsinfo(nmp, vp, cred, p); if (ioflag & (IO_APPEND | IO_SYNC)) { if (np->n_flag & NMODIFIED) { - np->n_attrstamp = 0; + np->n_xid = 0; error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1); if (error) { FSDBG_BOT(515, vp, uio->uio_offset, 0x10bad01, error); @@ -1544,7 +1544,7 @@ nfs_write(ap) } } if (ioflag & IO_APPEND) { - np->n_attrstamp = 0; + np->n_xid = 0; error = VOP_GETATTR(vp, &vattr, cred, p); if (error) { FSDBG_BOT(515, vp, uio->uio_offset, 0x10bad02, error); diff --git a/bsd/nfs/nfs_lock.c b/bsd/nfs/nfs_lock.c index 4edfce39a..e63ab6f25 100644 --- a/bsd/nfs/nfs_lock.c +++ b/bsd/nfs/nfs_lock.c @@ -233,14 +233,14 @@ nfs_dolock(struct vop_advlock_args *ap) /* need to flush, and refetch attributes to make */ /* sure we have the correct end of file offset */ if (np->n_flag & NMODIFIED) { - np->n_attrstamp = 0; + np->n_xid = 0; error = nfs_vinvalbuf(vp, V_SAVE, p->p_ucred, p, 1); if (error) { vrele(wvp); return (error); } } - np->n_attrstamp = 0; + np->n_xid = 0; error = VOP_GETATTR(vp, &vattr, p->p_ucred, p); if (error) { vrele(wvp); diff --git a/bsd/nfs/nfs_subs.c b/bsd/nfs/nfs_subs.c index a4d2cf088..98b3acd8b 100644 --- a/bsd/nfs/nfs_subs.c +++ b/bsd/nfs/nfs_subs.c @@ -1332,7 +1332,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink, xidp) * to indicate the attributes were dropped - only getattr * cares - it needs to retry the rpc. */ - np->n_attrstamp = 0; + np->n_xid = 0; FSDBG_BOT(527, 0, np, np->n_xid, *xidp); *xidp = 0; return (0); @@ -1437,7 +1437,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink, xidp) if (!UBCINFOEXISTS(vp) || dontshrink && np->n_size < ubc_getsize(vp)) { vap->va_size = np->n_size = orig_size; - np->n_attrstamp = 0; + np->n_xid = 0; } else { ubc_setsize(vp, (off_t)np->n_size); /* XXX */ } @@ -1473,6 +1473,12 @@ nfs_getattrcache(vp, vaper) struct timeval now, nowup; int32_t timeo; + if (np->n_xid == 0) { + FSDBG(528, vp, 0, 0, 0); + nfsstats.attrcache_misses++; + return (ENOENT); + } + /* Set attribute timeout based on how recently the file has been modified. */ if ((np)->n_flag & NMODIFIED) timeo = NFS_MINATTRTIMO; diff --git a/bsd/nfs/nfs_vnops.c b/bsd/nfs/nfs_vnops.c index 882ed59fe..986472153 100644 --- a/bsd/nfs/nfs_vnops.c +++ b/bsd/nfs/nfs_vnops.c @@ -711,7 +711,7 @@ nfs_open(ap) if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 1)) == EINTR) return (error); - np->n_attrstamp = 0; + np->n_xid = 0; if (vp->v_type == VDIR) np->n_direofoffset = 0; error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p); @@ -741,7 +741,7 @@ nfs_open(ap) } } if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) - np->n_attrstamp = 0; /* For Open/Close consistency */ + np->n_xid = 0; /* For Open/Close consistency */ return (0); } @@ -825,7 +825,7 @@ nfs_close(ap) } else { error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 1); } - np->n_attrstamp = 0; + np->n_xid = 0; if (getlock) VOP_UNLOCK(vp, 0, ap->a_p); } @@ -1210,7 +1210,7 @@ nfs_setattrrpc(vp, vap, cred, procp) if (v3) { nfsm_wcc_data(vp, wccflag, &xid); if (!wccflag) - VTONFS(vp)->n_attrstamp = 0; + VTONFS(vp)->n_xid = 0; } else nfsm_loadattr(vp, (struct vattr *)0, &xid); nfsm_reqdone; @@ -1833,7 +1833,7 @@ nfs_mknodrpc(dvp, vpp, cnp, vap) } VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) - VTONFS(dvp)->n_attrstamp = 0; + VTONFS(dvp)->n_xid = 0; vput(dvp); NFS_FREE_PNBUF(cnp); return (error); @@ -1970,7 +1970,7 @@ again: } VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) - VTONFS(dvp)->n_attrstamp = 0; + VTONFS(dvp)->n_xid = 0; vput(dvp); NFS_FREE_PNBUF(cnp); return (error); @@ -2075,7 +2075,7 @@ nfs_remove(ap) } else if (!np->n_sillyrename) { error = nfs_sillyrename(dvp, vp, cnp); } - np->n_attrstamp = 0; + np->n_xid = 0; vput(dvp); VOP_UNLOCK(vp, 0, cnp->cn_proc); @@ -2133,7 +2133,7 @@ nfs_removerpc(dvp, name, namelen, cred, proc) nfsm_reqdone; VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) - VTONFS(dvp)->n_attrstamp = 0; + VTONFS(dvp)->n_xid = 0; return (error); } @@ -2317,10 +2317,10 @@ nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, proc) nfsm_reqdone; VTONFS(fdvp)->n_flag |= NMODIFIED; if (!fwccflag) - VTONFS(fdvp)->n_attrstamp = 0; + VTONFS(fdvp)->n_xid = 0; VTONFS(tdvp)->n_flag |= NMODIFIED; if (!twccflag) - VTONFS(tdvp)->n_attrstamp = 0; + VTONFS(tdvp)->n_xid = 0; return (error); } @@ -2394,9 +2394,9 @@ nfs_link(ap) VTONFS(tdvp)->n_flag |= NMODIFIED; if (!attrflag) - VTONFS(vp)->n_attrstamp = 0; + VTONFS(vp)->n_xid = 0; if (!wccflag) - VTONFS(tdvp)->n_attrstamp = 0; + VTONFS(tdvp)->n_xid = 0; if (didhold) ubc_rele(vp); vput(tdvp); @@ -2472,7 +2472,7 @@ nfs_symlink(ap) VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) - VTONFS(dvp)->n_attrstamp = 0; + VTONFS(dvp)->n_xid = 0; vput(dvp); NFS_FREE_PNBUF(cnp); /* @@ -2546,7 +2546,7 @@ nfs_mkdir(ap) nfsm_reqdone; VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) - VTONFS(dvp)->n_attrstamp = 0; + VTONFS(dvp)->n_xid = 0; /* * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry * if we can succeed in looking up the directory. @@ -2608,7 +2608,7 @@ nfs_rmdir(ap) nfsm_reqdone; VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) - VTONFS(dvp)->n_attrstamp = 0; + VTONFS(dvp)->n_xid = 0; cache_purge(dvp); cache_purge(vp); vput(vp); diff --git a/config/System.kext/Info.plist b/config/System.kext/Info.plist index e259100dd..b3403bec6 100644 --- a/config/System.kext/Info.plist +++ b/config/System.kext/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - System Resource Pseudoextension, Apple Computer Inc, 7.0 + System Resource Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.kernel CFBundleInfoDictionaryVersion @@ -15,13 +15,13 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleCompatibleVersion - 7.0 + 7.2 OSBundleRequired Root OSKernelResource diff --git a/config/System.kext/PlugIns/AppleNMI.kext/Info.plist b/config/System.kext/PlugIns/AppleNMI.kext/Info.plist index 8bb6e3818..17c0b5965 100644 --- a/config/System.kext/PlugIns/AppleNMI.kext/Info.plist +++ b/config/System.kext/PlugIns/AppleNMI.kext/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - AppleNMI Pseudoextension, Apple Computer Inc, 7.0 + AppleNMI Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.driver.AppleNMI CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleRequired Root OSKernelResource diff --git a/config/System.kext/PlugIns/ApplePlatformFamily.kext/Info.plist b/config/System.kext/PlugIns/ApplePlatformFamily.kext/Info.plist index 553282439..634c0a048 100644 --- a/config/System.kext/PlugIns/ApplePlatformFamily.kext/Info.plist +++ b/config/System.kext/PlugIns/ApplePlatformFamily.kext/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - Apple Platform Family Pseudoextension, Apple Computer Inc, 7.0 + Apple Platform Family Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.iokit.ApplePlatformFamily CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleCompatibleVersion 1.0 OSBundleRequired diff --git a/config/System.kext/PlugIns/BSDKernel.kext/Info.plist b/config/System.kext/PlugIns/BSDKernel.kext/Info.plist index a77384459..adc04c935 100644 --- a/config/System.kext/PlugIns/BSDKernel.kext/Info.plist +++ b/config/System.kext/PlugIns/BSDKernel.kext/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable BSDKernel CFBundleGetInfoString - BSD Kernel Pseudoextension, Apple Computer Inc, 7.0 + BSD Kernel Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.kpi.bsd CFBundleInfoDictionaryVersion @@ -17,13 +17,13 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleCompatibleVersion - 7.0 + 7.2 OSBundleRequired Root OSKernelResource diff --git a/config/System.kext/PlugIns/IOKit.kext/Info.plist b/config/System.kext/PlugIns/IOKit.kext/Info.plist index 236a023ea..8267cff18 100644 --- a/config/System.kext/PlugIns/IOKit.kext/Info.plist +++ b/config/System.kext/PlugIns/IOKit.kext/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable IOKit CFBundleGetInfoString - I/O Kit Pseudoextension, Apple Computer Inc, 7.0 + I/O Kit Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.kpi.iokit CFBundleInfoDictionaryVersion @@ -17,13 +17,13 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleCompatibleVersion - 7.0 + 7.2 OSBundleRequired Root OSKernelResource diff --git a/config/System.kext/PlugIns/IONVRAMFamily.kext/Info.plist b/config/System.kext/PlugIns/IONVRAMFamily.kext/Info.plist index d29160140..4769d258e 100644 --- a/config/System.kext/PlugIns/IONVRAMFamily.kext/Info.plist +++ b/config/System.kext/PlugIns/IONVRAMFamily.kext/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - AppleNMI Pseudoextension, Apple Computer Inc, 7.0 + AppleNMI Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.iokit.IONVRAMFamily CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleCompatibleVersion 1.1 OSBundleRequired diff --git a/config/System.kext/PlugIns/IOSystemManagement.kext/Info.plist b/config/System.kext/PlugIns/IOSystemManagement.kext/Info.plist index 9be693d71..714bbe7e3 100644 --- a/config/System.kext/PlugIns/IOSystemManagement.kext/Info.plist +++ b/config/System.kext/PlugIns/IOSystemManagement.kext/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleGetInfoString - System Management Pseudoextension, Apple Computer Inc, 7.0 + System Management Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.iokit.IOSystemManagementFamily CFBundleInfoDictionaryVersion @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleCompatibleVersion 1.0.0b1 OSBundleRequired diff --git a/config/System.kext/PlugIns/Libkern.kext/Info.plist b/config/System.kext/PlugIns/Libkern.kext/Info.plist index c88f26282..cd2bda1d2 100644 --- a/config/System.kext/PlugIns/Libkern.kext/Info.plist +++ b/config/System.kext/PlugIns/Libkern.kext/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Libkern CFBundleGetInfoString - Libkern Pseudoextension, Apple Computer Inc, 7.0 + Libkern Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.kpi.libkern CFBundleInfoDictionaryVersion @@ -17,13 +17,13 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleCompatibleVersion - 7.0 + 7.2 OSBundleRequired Root OSKernelResource diff --git a/config/System.kext/PlugIns/Mach.kext/Info.plist b/config/System.kext/PlugIns/Mach.kext/Info.plist index ee1c118ba..a87c1060d 100644 --- a/config/System.kext/PlugIns/Mach.kext/Info.plist +++ b/config/System.kext/PlugIns/Mach.kext/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Mach CFBundleGetInfoString - Mach Kernel Pseudoextension, Apple Computer Inc, 7.0 + Mach Kernel Pseudoextension, Apple Computer Inc, 7.2 CFBundleIdentifier com.apple.kpi.mach CFBundleInfoDictionaryVersion @@ -17,13 +17,13 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 7.0 + 7.2 CFBundleSignature ???? CFBundleVersion - 7.0 + 7.2 OSBundleCompatibleVersion - 7.0 + 7.2 OSBundleRequired Root OSKernelResource diff --git a/iokit/KernelConfigTables.cpp b/iokit/KernelConfigTables.cpp index 121b6e13f..d3e777516 100644 --- a/iokit/KernelConfigTables.cpp +++ b/iokit/KernelConfigTables.cpp @@ -29,15 +29,15 @@ */ const char * gIOKernelKmods = "{" -" 'com.apple.kernel' = '7.0';" -" 'com.apple.kpi.bsd' = '7.0';" -" 'com.apple.kpi.iokit' = '7.0';" -" 'com.apple.kpi.libkern' = '7.0';" -" 'com.apple.kpi.mach' = '7.0';" -" 'com.apple.iokit.IONVRAMFamily' = '7.0';" -" 'com.apple.driver.AppleNMI' = '7.0';" -" 'com.apple.iokit.IOSystemManagementFamily' = '7.0';" -" 'com.apple.iokit.ApplePlatformFamily' = '7.0';" +" 'com.apple.kernel' = '7.2';" +" 'com.apple.kpi.bsd' = '7.2';" +" 'com.apple.kpi.iokit' = '7.2';" +" 'com.apple.kpi.libkern' = '7.2';" +" 'com.apple.kpi.mach' = '7.2';" +" 'com.apple.iokit.IONVRAMFamily' = '7.2';" +" 'com.apple.driver.AppleNMI' = '7.2';" +" 'com.apple.iokit.IOSystemManagementFamily' = '7.2';" +" 'com.apple.iokit.ApplePlatformFamily' = '7.2';" " 'com.apple.kernel.6.0' = '6.9.9';" " 'com.apple.kernel.bsd' = '6.9.9';" " 'com.apple.kernel.iokit' = '6.9.9';" diff --git a/iokit/conf/version.minor b/iokit/conf/version.minor index 573541ac9..0cfbf0888 100644 --- a/iokit/conf/version.minor +++ b/iokit/conf/version.minor @@ -1 +1 @@ -0 +2 diff --git a/libkern/conf/version.minor b/libkern/conf/version.minor index 573541ac9..0cfbf0888 100644 --- a/libkern/conf/version.minor +++ b/libkern/conf/version.minor @@ -1 +1 @@ -0 +2 diff --git a/libsa/conf/version.minor b/libsa/conf/version.minor index 573541ac9..0cfbf0888 100644 --- a/libsa/conf/version.minor +++ b/libsa/conf/version.minor @@ -1 +1 @@ -0 +2 diff --git a/osfmk/conf/kernelversion.minor b/osfmk/conf/kernelversion.minor index 573541ac9..0cfbf0888 100644 --- a/osfmk/conf/kernelversion.minor +++ b/osfmk/conf/kernelversion.minor @@ -1 +1 @@ -0 +2 diff --git a/osfmk/conf/version.minor b/osfmk/conf/version.minor index 573541ac9..0cfbf0888 100644 --- a/osfmk/conf/version.minor +++ b/osfmk/conf/version.minor @@ -1 +1 @@ -0 +2 diff --git a/osfmk/ppc/cswtch.s b/osfmk/ppc/cswtch.s index b5bf7db2c..8cbf06cfb 100644 --- a/osfmk/ppc/cswtch.s +++ b/osfmk/ppc/cswtch.s @@ -61,11 +61,15 @@ LEXT(machine_load_context) mfmsr r5 /* Since we are passing control, get our MSR values */ lwz r11,SAVprev+4(r3) /* Get the previous savearea */ lwz r1,saver1+4(r3) /* Load new stack pointer */ + lwz r10,ACT_MACT_SPF(r9) /* Get the special flags */ stw r0,saver3+4(r3) /* Make sure we pass in a 0 for the continuation */ stw r0,FM_BACKPTR(r1) /* zero backptr */ stw r5,savesrr1+4(r3) /* Pass our MSR to the new guy */ stw r11,ACT_MACT_PCB(r9) /* Unstack our savearea */ + oris r10,r10,hi16(OnProc) /* Set OnProc bit */ stw r0,ACT_PREEMPT_CNT(r9) /* Enable preemption */ + stw r10,ACT_MACT_SPF(r9) /* Update the special flags */ + stw r10,spcFlags(r6) /* Set per_proc copy of the special flags */ b EXT(exception_exit) /* Go for it */ /* thread_t Switch_context(thread_t old, diff --git a/osfmk/ppc/genassym.c b/osfmk/ppc/genassym.c index de20106ce..3a5d1edb5 100644 --- a/osfmk/ppc/genassym.c +++ b/osfmk/ppc/genassym.c @@ -124,6 +124,8 @@ int main(int argc, char *argv[]) DECLARE("FamVMmodebit", FamVMmodebit); DECLARE("perfMonitor", perfMonitor); DECLARE("perfMonitorbit", perfMonitorbit); + DECLARE("OnProc", OnProc); + DECLARE("OnProcbit", OnProcbit); /* Per Proc info structure */ DECLARE("PP_CPU_NUMBER", offsetof(struct per_proc_info *, cpu_number)); diff --git a/osfmk/ppc/hw_exception.s b/osfmk/ppc/hw_exception.s index ee177d39f..9e9fa5aa8 100644 --- a/osfmk/ppc/hw_exception.s +++ b/osfmk/ppc/hw_exception.s @@ -1255,7 +1255,7 @@ vmxonlyone: stw r24,VMXsave(r20) ; Dequeue this savearea lwz r3,SACvrswap+4(r3) ; Get the virtual to real conversion (bottom) stw r8,SAVprev(r22) ; Link the old in (top) stw r9,SAVprev+4(r22) ; Link the old in (bottom) - xor r3,r24,r3 ; Convert to physical + xor r3,r22,r3 ; Convert to physical stw r2,quickfret(r31) ; Set the first in quickfret list (top) stw r3,quickfret+4(r31) ; Set the first in quickfret list (bottom) diff --git a/osfmk/ppc/hw_lock.s b/osfmk/ppc/hw_lock.s index 1b2352d36..d7212fe01 100644 --- a/osfmk/ppc/hw_lock.s +++ b/osfmk/ppc/hw_lock.s @@ -919,23 +919,86 @@ LEXT(_mutex_lock) #if !MACH_LDEBUG mfsprg r6,1 ; load the current thread lwz r5,0(r3) ; Get the lock quickly + li r4,0 + li r8,0 mr. r5,r5 ; Quick check - bne-- L_mutex_lock_slow ; Can not get it right now... + bne-- mlckspin1 ; Can not get it right now... -L_mutex_lock_loop: +mlcktry: lwarx r5,0,r3 ; load the mutex lock mr. r5,r5 - bne-- L_mutex_lock_slowX ; go to the slow path + bne-- mlckspin0 ; Can not get it right now... stwcx. r6,0,r3 ; grab the lock - bne-- L_mutex_lock_loop ; loop back if failed + bne-- mlcktry ; loop back if failed isync ; stop prefeteching + mflr r8 + stw r8,4(r3) blr -L_mutex_lock_slowX: +mlckspin0: li r5,lgKillResv ; Killing field stwcx. r5,0,r5 ; Kill reservation +mlckspin1: + mr. r4,r4 ; Test timeout value + bne++ mlckspin2 + lis r4,hi16(EXT(MutexSpin)) ; Get the high part + ori r4,r4,lo16(EXT(MutexSpin) ) ; And the low part + lwz r4,0(r4) ; Get spin timerout value + mr. r4,r4 ; Test spin timeout value + beq mlckslow1 ; Is spin timeout set to zero + +mlckspin2: mr. r8,r8 ; Is r8 set to zero + bne++ mlckspin3 ; If yes, first spin attempt + lis r0,hi16(MASK(MSR_VEC)) ; Get vector enable + mfmsr r9 ; Get the MSR value + ori r0,r0,lo16(MASK(MSR_FP)) ; Get FP enable + ori r7,r0,lo16(MASK(MSR_EE)) ; Get EE bit on too + andc r9,r9,r0 ; Clear FP and VEC + andc r7,r9,r7 ; Clear EE as well + mtmsr r7 ; Turn off interruptions + isync ; May have turned off vec and fp here + mftb r8 ; Get timestamp on entry + b mlcksniff + +mlckspin3: mtmsr r7 ; Turn off interruptions + mftb r8 ; Get timestamp on entry + +mlcksniff: lwz r5,0(r3) ; Get that lock in here + mr. r5,r5 ; Is the lock held + beq++ mlckretry ; No, try for it again... + rlwinm r5,r5,0,0,29 ; Extract the lock owner + mr. r5,r5 ; Quick check + beq++ mlckslow0 ; InterLock is held + lwz r10,ACT_MACT_SPF(r5) ; Get the special flags + rlwinm. r10,r10,0,OnProcbit,OnProcbit ; Is OnProcbit set? + beq mlckslow0 ; Lock owner isn't running + + mftb r10 ; Time stamp us now + sub r10,r10,r8 ; Get the elapsed time + cmplwi r10,128 ; Have we been spinning for 128 tb ticks? + blt++ mlcksniff ; Not yet... + + mtmsr r9 ; Say, any interrupts pending? + +; The following instructions force the pipeline to be interlocked to that only one +; instruction is issued per cycle. The insures that we stay enabled for a long enough +; time; if it's too short, pending interruptions will not have a chance to be taken + + subi r4,r4,128 ; Back off elapsed time from timeout value + or r4,r4,r4 ; Do nothing here but force a single cycle delay + mr. r4,r4 ; See if we used the whole timeout + or r4,r4,r4 ; Do nothing here but force a single cycle delay + + ble-- mlckslow1 ; We failed + b mlckspin1 ; Now that we've opened an enable window, keep trying... +mlckretry: + mtmsr r9 ; Restore interrupt state + li r8,1 ; Show already through once + b mlcktry +mlckslow0: ; We couldn't get the lock + mtmsr r9 ; Restore interrupt state -L_mutex_lock_slow: +mlckslow1: #endif #if CHECKNMI mflr r12 ; (TEST/DEBUG) diff --git a/osfmk/ppc/hw_vm.s b/osfmk/ppc/hw_vm.s index 0a4c4c2ea..7dc3aa18e 100644 --- a/osfmk/ppc/hw_vm.s +++ b/osfmk/ppc/hw_vm.s @@ -1680,6 +1680,9 @@ hpmCNext: bne++ cr1,hpmSearch ; There is another to check... hpmGotOne: lwz r20,mpFlags(r3) ; Get the flags andi. r9,r20,lo16(mpSpecial|mpNest|mpPerm|mpBlock) ; Are we allowed to remove it? + rlwinm r21,r20,8,24,31 ; Extract the busy count + cmplwi cr2,r21,0 ; Is it busy? + crand cr0_eq,cr2_eq,cr0_eq ; not busy and can be removed? beq++ hrmGotX ; Found, branch to remove the mapping... b hpmCNext ; Nope... diff --git a/osfmk/ppc/machine_routines.c b/osfmk/ppc/machine_routines.c index 51af4a3d3..c6c0dd611 100644 --- a/osfmk/ppc/machine_routines.c +++ b/osfmk/ppc/machine_routines.c @@ -33,6 +33,8 @@ #include unsigned int max_cpus_initialized = 0; +unsigned int LockTimeOut = 12500000; +unsigned int MutexSpin = 0; extern int forcenap; #define MAX_CPUS_SET 0x1 @@ -388,6 +390,25 @@ ml_enable_cache_level(int cache_level, int enable) return -1; } +void +ml_init_lock_timeout(void) +{ + uint64_t abstime; + uint32_t mtxspin; + + nanoseconds_to_absolutetime(NSEC_PER_SEC>>2, &abstime); + LockTimeOut = (unsigned int)abstime; + + if (PE_parse_boot_arg("mtxspin", &mtxspin)) { + if (mtxspin > USEC_PER_SEC>>4) + mtxspin = USEC_PER_SEC>>4; + nanoseconds_to_absolutetime(mtxspin*NSEC_PER_USEC, &abstime); + } else { + nanoseconds_to_absolutetime(20*NSEC_PER_USEC, &abstime); + } + MutexSpin = (unsigned int)abstime; +} + void init_ast_check(processor_t processor) {} diff --git a/osfmk/ppc/machine_routines.h b/osfmk/ppc/machine_routines.h index f767dcf4e..960084dac 100644 --- a/osfmk/ppc/machine_routines.h +++ b/osfmk/ppc/machine_routines.h @@ -220,6 +220,8 @@ void ml_thrm_set( unsigned int ml_throttle( unsigned int); +void ml_init_lock_timeout(void); + #endif /* MACH_KERNEL_PRIVATE */ void ml_thread_policy( diff --git a/osfmk/ppc/machine_routines_asm.s b/osfmk/ppc/machine_routines_asm.s index 32aeabef5..b19994b02 100644 --- a/osfmk/ppc/machine_routines_asm.s +++ b/osfmk/ppc/machine_routines_asm.s @@ -826,7 +826,7 @@ minoslownap: ; So, make sure everything we need there is already set up... ; - li r10,hi16(dozem|napm|sleepm) ; Mask of power management bits + lis r10,hi16(dozem|napm|sleepm) ; Mask of power management bits bf-- pf64Bitb,mipNSF1 ; skip if 32-bit... diff --git a/osfmk/ppc/pcb.c b/osfmk/ppc/pcb.c index 85fbf336c..cab866056 100644 --- a/osfmk/ppc/pcb.c +++ b/osfmk/ppc/pcb.c @@ -166,6 +166,8 @@ machine_switch_context( old_act->mact.specFlags &= ~(userProtKey|FamVMmode); old_act->mact.specFlags |= (ppinfo->spcFlags) & (userProtKey|FamVMmode); } + old_act->mact.specFlags &= ~OnProc; + new_act->mact.specFlags |= OnProc; /* * We do not have to worry about the PMAP module, so switch. @@ -697,6 +699,8 @@ machine_stack_handoff( old->top_act->mact.specFlags &= ~(userProtKey|FamVMmode); old->top_act->mact.specFlags |= (ppinfo->spcFlags) & (userProtKey|FamVMmode); } + old->top_act->mact.specFlags &= ~OnProc; + new->top_act->mact.specFlags |= OnProc; KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED,MACH_STACK_HANDOFF) | DBG_FUNC_NONE, old->reason, (int)new, old->sched_pri, new->sched_pri, 0); diff --git a/osfmk/ppc/rtclock.c b/osfmk/ppc/rtclock.c index 0ee1b0476..08a4bc6df 100644 --- a/osfmk/ppc/rtclock.c +++ b/osfmk/ppc/rtclock.c @@ -45,6 +45,7 @@ #include /* HZ */ #include +#include #include #include @@ -191,6 +192,8 @@ timebase_callback( nanoseconds_to_absolutetime(NSEC_PER_HZ, &abstime); rtclock_tick_interval = abstime; + + ml_init_lock_timeout(); } else { UNLOCK_RTC(s); diff --git a/osfmk/ppc/thread_act.h b/osfmk/ppc/thread_act.h index 7438f3170..e648da76d 100644 --- a/osfmk/ppc/thread_act.h +++ b/osfmk/ppc/thread_act.h @@ -129,6 +129,7 @@ typedef struct MachineThrAct { #define FamVMenabit 11 #define FamVMmodebit 12 #define perfMonitorbit 13 +#define OnProcbit 14 /* NOTE: Do not move or assign bit 31 without changing exception vector ultra fast path code */ #define bbThreadbit 28 #define bbNoMachSCbit 29 @@ -149,6 +150,7 @@ typedef struct MachineThrAct { #define FamVMena 0x00100000 /* (1<<(31-FamVMenabit)) */ #define FamVMmode 0x00080000 /* (1<<(31-FamVMmodebit)) */ #define perfMonitor 0x00040000 /* (1<<(31-perfMonitorbit)) */ +#define OnProc 0x00020000 /* (1<<(31-OnProcbit)) */ #define bbThread 0x00000008 /* (1<<(31-bbThreadbit)) */ #define bbNoMachSC 0x00000004 /* (1<<(31-bbNoMachSCbit)) */ diff --git a/osfmk/vm/vm_pageout.c b/osfmk/vm/vm_pageout.c index 19a6eb885..82c4ba678 100644 --- a/osfmk/vm/vm_pageout.c +++ b/osfmk/vm/vm_pageout.c @@ -1119,9 +1119,32 @@ void vm_pageout_throttle( register vm_page_t m) { + register vm_object_t object; + + /* + * need to keep track of the object we + * started with... if we drop the object lock + * due to the throttle, it's possible that someone + * else will gather this page into an I/O if this + * is an external object... the page will then be + * potentially freed before we unwedge from the + * throttle... this is ok since no one plays with + * the page directly after the throttle... the object + * and offset are passed into the memory_object_data_return + * function where eventually it's relooked up against the + * object... if it's changed state or there is no longer + * a page at that offset, the pageout just finishes without + * issuing an I/O + */ + object = m->object; + assert(!m->laundry); m->laundry = TRUE; - while (vm_page_laundry_count >= vm_page_laundry_max) { + if (!object->internal) + vm_page_burst_count++; + vm_page_laundry_count++; + + while (vm_page_laundry_count > vm_page_laundry_max) { /* * Set the threshold for when vm_page_free() * should wake us up. @@ -1130,18 +1153,15 @@ vm_pageout_throttle( assert_wait((event_t) &vm_page_laundry_count, THREAD_UNINT); vm_page_unlock_queues(); - vm_object_unlock(m->object); + vm_object_unlock(object); /* * Pause to let the default pager catch up. */ thread_block((void (*)(void)) 0); - vm_object_lock(m->object); + vm_object_lock(object); vm_page_lock_queues(); } - if (!m->object->internal) - vm_page_burst_count++; - vm_page_laundry_count++; } /* diff --git a/pexpert/conf/version.minor b/pexpert/conf/version.minor index 573541ac9..0cfbf0888 100644 --- a/pexpert/conf/version.minor +++ b/pexpert/conf/version.minor @@ -1 +1 @@ -0 +2 diff --git a/pexpert/ppc/pe_identify_machine.c b/pexpert/ppc/pe_identify_machine.c index 558d6bd65..16f0cd59d 100644 --- a/pexpert/ppc/pe_identify_machine.c +++ b/pexpert/ppc/pe_identify_machine.c @@ -27,10 +27,6 @@ #include #include -/* External declarations */ - -unsigned int LockTimeOut = 12500000; - /* pe_identify_machine: * * Sets up platform parameters. -- 2.45.2