diff options
author | dm120769 <none@none> | 2008-04-25 20:19:02 -0700 |
---|---|---|
committer | dm120769 <none@none> | 2008-04-25 20:19:02 -0700 |
commit | c6c65e5445ba6bc005f3da488bddd36494d26e65 (patch) | |
tree | b769322e7f726d81a4e2a3c7ce53ba85d28c2ecc /usr/src/uts/common/os/move.c | |
parent | 0cfb4e8b28ab16b0cb224619362e8135673714c3 (diff) | |
download | illumos-joyent-c6c65e5445ba6bc005f3da488bddd36494d26e65.tar.gz |
backout 6567008/6582323/6582330/6582335/6691271: needs more work
--HG--
rename : usr/src/pkgdefs/SUNWdcopy/Makefile => deleted_files/usr/src/pkgdefs/SUNWdcopy/Makefile
rename : usr/src/pkgdefs/SUNWdcopy/pkginfo.tmpl => deleted_files/usr/src/pkgdefs/SUNWdcopy/pkginfo.tmpl
rename : usr/src/pkgdefs/SUNWdcopy/postinstall.tmpl => deleted_files/usr/src/pkgdefs/SUNWdcopy/postinstall.tmpl
rename : usr/src/pkgdefs/SUNWdcopy/preremove.tmpl => deleted_files/usr/src/pkgdefs/SUNWdcopy/preremove.tmpl
rename : usr/src/pkgdefs/SUNWdcopy/prototype_com => deleted_files/usr/src/pkgdefs/SUNWdcopy/prototype_com
rename : usr/src/pkgdefs/SUNWdcopy/prototype_i386 => deleted_files/usr/src/pkgdefs/SUNWdcopy/prototype_i386
rename : usr/src/uts/common/io/dcopy.c => deleted_files/usr/src/uts/common/io/dcopy.c
rename : usr/src/uts/common/sys/dcopy.h => deleted_files/usr/src/uts/common/sys/dcopy.h
rename : usr/src/uts/common/sys/dcopy_device.h => deleted_files/usr/src/uts/common/sys/dcopy_device.h
rename : usr/src/uts/common/sys/sodirect.h => deleted_files/usr/src/uts/common/sys/sodirect.h
rename : usr/src/uts/i86pc/io/ioat/ioat.c => deleted_files/usr/src/uts/i86pc/io/ioat/ioat.c
rename : usr/src/uts/i86pc/io/ioat/ioat.conf => deleted_files/usr/src/uts/i86pc/io/ioat/ioat.conf
rename : usr/src/uts/i86pc/io/ioat/ioat_chan.c => deleted_files/usr/src/uts/i86pc/io/ioat/ioat_chan.c
rename : usr/src/uts/i86pc/io/ioat/ioat_ioctl.c => deleted_files/usr/src/uts/i86pc/io/ioat/ioat_ioctl.c
rename : usr/src/uts/i86pc/io/ioat/ioat_rs.c => deleted_files/usr/src/uts/i86pc/io/ioat/ioat_rs.c
rename : usr/src/uts/i86pc/ioat/Makefile => deleted_files/usr/src/uts/i86pc/ioat/Makefile
rename : usr/src/uts/i86pc/sys/ioat.h => deleted_files/usr/src/uts/i86pc/sys/ioat.h
rename : usr/src/uts/i86xpv/ioat/Makefile => deleted_files/usr/src/uts/i86xpv/ioat/Makefile
rename : usr/src/uts/intel/dcopy/Makefile => deleted_files/usr/src/uts/intel/dcopy/Makefile
Diffstat (limited to 'usr/src/uts/common/os/move.c')
-rw-r--r-- | usr/src/uts/common/os/move.c | 384 |
1 files changed, 4 insertions, 380 deletions
diff --git a/usr/src/uts/common/os/move.c b/usr/src/uts/common/os/move.c index f4056aa02c..d5c63b167e 100644 --- a/usr/src/uts/common/os/move.c +++ b/usr/src/uts/common/os/move.c @@ -2,8 +2,9 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -44,16 +45,6 @@ #include <sys/systm.h> #include <sys/uio.h> #include <sys/errno.h> -#include <sys/vmsystm.h> -#include <sys/cmn_err.h> -#include <vm/as.h> -#include <vm/page.h> - -#include <sys/dcopy.h> - -int64_t uioa_maxpoll = -1; /* <0 = noblock, 0 = block, >0 = block after */ -#define UIO_DCOPY_CHANNEL 0 -#define UIO_DCOPY_CMD 1 /* * Move "n" bytes at byte address "p"; "rw" indicates the direction @@ -286,370 +277,3 @@ uiodup(uio_t *suio, uio_t *duio, iovec_t *diov, int diov_cnt) duio->uio_iov = diov; return (0); } - -/* - * Shadow state for checking if a platform has hardware asynchronous - * copy capability and minimum copy size, e.g. Intel's I/OAT dma engine, - * /dev/dcopy. - */ -uioasync_t uioasync = {B_TRUE, 1024}; - -/* - * Schedule an asynchronous move of "n" bytes at byte address "p", - * "rw" indicates the direction of the move, I/O parameters and - * async state are provided in "uioa" which is update to reflect - * the data which is to be moved. - * - * Returns 0 on success or a non-zero errno on failure. - * - * Note, while the uioasync APIs are general purpose in design - * the current implementation is Intel I/OAT specific. - */ -int -uioamove(void *p, size_t n, enum uio_rw rw, uioa_t *uioa) -{ - int soff, doff; - uint64_t pa; - int cnt; - iovec_t *iov; - dcopy_handle_t channel; - dcopy_cmd_t cmd; - int ret = 0; - int dcopy_flags; - - if (!(uioa->uioa_state & UIOA_ENABLED)) { - /* The uioa_t isn't enabled */ - return (ENXIO); - } - - if (uioa->uio_segflg != UIO_USERSPACE || rw != UIO_READ) { - /* Only support to user-land from kernel */ - return (ENOTSUP); - } - - - channel = uioa->uioa_hwst[UIO_DCOPY_CHANNEL]; - cmd = uioa->uioa_hwst[UIO_DCOPY_CMD]; - dcopy_flags = DCOPY_NOSLEEP; - - /* - * While source bytes and destination bytes. - */ - while (n > 0 && uioa->uio_resid > 0) { - iov = uioa->uio_iov; - if (iov->iov_len == 0l) { - uioa->uio_iov++; - uioa->uio_iovcnt--; - uioa->uioa_lcur++; - uioa->uioa_lppp = uioa->uioa_lcur->uioa_ppp; - continue; - } - /* - * While source bytes schedule an async - * dma for destination page by page. - */ - while (n > 0) { - /* Addr offset in page src/dst */ - soff = (uintptr_t)p & PAGEOFFSET; - doff = (uintptr_t)iov->iov_base & PAGEOFFSET; - /* Min copy count src and dst and page sized */ - cnt = MIN(n, iov->iov_len); - cnt = MIN(cnt, PAGESIZE - soff); - cnt = MIN(cnt, PAGESIZE - doff); - /* XXX if next page(s) contiguous could use multipage */ - - /* - * if we have an old command, we want to link all - * other commands to the next command we alloced so - * we only need to track the last command but can - * still free them all. - */ - if (cmd != NULL) { - dcopy_flags |= DCOPY_ALLOC_LINK; - } - ret = dcopy_cmd_alloc(channel, dcopy_flags, &cmd); - if (ret != DCOPY_SUCCESS) { - /* Error of some sort */ - return (EIO); - } - uioa->uioa_hwst[UIO_DCOPY_CMD] = cmd; - - ASSERT(cmd->dp_version == DCOPY_CMD_V0); - if (uioa_maxpoll >= 0) { - /* Blocking (>0 may be) used in uioafini() */ - cmd->dp_flags = DCOPY_CMD_INTR; - } else { - /* Non blocking uioafini() so no intr */ - cmd->dp_flags = DCOPY_CMD_NOFLAGS; - } - cmd->dp_cmd = DCOPY_CMD_COPY; - pa = ptob((uint64_t)hat_getpfnum(kas.a_hat, p)); - cmd->dp.copy.cc_source = pa + soff; - if (uioa->uioa_lcur->uioa_pfncnt == 0) { - /* Have a (page_t **) */ - pa = ptob((uint64_t)( - *(page_t **)uioa->uioa_lppp)->p_pagenum); - } else { - /* Have a (pfn_t *) */ - pa = ptob((uint64_t)( - *(pfn_t *)uioa->uioa_lppp)); - } - cmd->dp.copy.cc_dest = pa + doff; - cmd->dp.copy.cc_size = cnt; - ret = dcopy_cmd_post(cmd); - if (ret != DCOPY_SUCCESS) { - /* Error of some sort */ - return (EIO); - } - ret = 0; - - /* If UIOA_POLL not set, set it */ - if (!(uioa->uioa_state & UIOA_POLL)) - uioa->uioa_state |= UIOA_POLL; - - /* Update iov, uio, and local pointers/counters */ - iov->iov_base += cnt; - iov->iov_len -= cnt; - uioa->uio_resid -= cnt; - uioa->uio_loffset += cnt; - p = (caddr_t)p + cnt; - n -= cnt; - - /* End of iovec? */ - if (iov->iov_len == 0) { - /* Yup, next iovec */ - break; - } - - /* Next dst addr page? */ - if (doff + cnt == PAGESIZE) { - /* Yup, next page_t */ - uioa->uioa_lppp++; - } - } - } - - return (ret); -} - -/* - * Initialize a uioa_t for a given uio_t for the current user context, - * copy the common uio_t to the uioa_t, walk the shared iovec_t and - * lock down the user-land page(s) containing iovec_t data, then mapin - * user-land pages using segkpm. - */ -int -uioainit(uio_t *uiop, uioa_t *uioap) -{ - caddr_t addr; - page_t **pages; - int off; - int len; - proc_t *procp = ttoproc(curthread); - struct as *as = procp->p_as; - iovec_t *iov = uiop->uio_iov; - int32_t iovcnt = uiop->uio_iovcnt; - uioa_page_t *locked = uioap->uioa_locked; - dcopy_handle_t channel; - int error; - - if (! (uioap->uioa_state & UIOA_ALLOC)) { - /* Can only init() a freshly allocated uioa_t */ - return (EINVAL); - } - - error = dcopy_alloc(DCOPY_NOSLEEP, &channel); - if (error == DCOPY_NORESOURCES) { - /* Turn off uioa */ - uioasync.enabled = B_FALSE; - return (ENODEV); - } - if (error != DCOPY_SUCCESS) { - /* Alloc failed */ - return (EIO); - } - - uioap->uioa_hwst[UIO_DCOPY_CHANNEL] = channel; - uioap->uioa_hwst[UIO_DCOPY_CMD] = NULL; - - /* Indicate uioa_t (will be) initialized */ - uioap->uioa_state = UIOA_INIT; - - /* uio_t/uioa_t uio_t common struct copy */ - *((uio_t *)uioap) = *uiop; - - /* initialize *uiop->uio_iov */ - if (iovcnt > UIOA_IOV_MAX) { - /* Too big? */ - return (E2BIG); - } - uioap->uio_iov = iov; - uioap->uio_iovcnt = iovcnt; - - /* Mark the uioap as such */ - uioap->uio_extflg |= UIO_ASYNC; - - /* - * For each iovec_t, lock-down the page(s) backing the iovec_t - * and save the page_t list for phys addr use in uioamove(). - */ - iov = uiop->uio_iov; - iovcnt = uiop->uio_iovcnt; - while (iovcnt > 0) { - addr = iov->iov_base; - off = (uintptr_t)addr & PAGEOFFSET; - addr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK); - len = iov->iov_len + off; - - /* Lock down page(s) for the iov span */ - if ((error = as_pagelock(as, &pages, - iov->iov_base, iov->iov_len, S_WRITE)) != 0) { - /* Error */ - goto cleanup; - } - - if (pages == NULL) { - /* - * Need page_t list, really only need - * a pfn list so build one. - */ - pfn_t *pfnp; - int pcnt = len >> PAGESHIFT; - - if (off) - pcnt++; - if ((pfnp = kmem_alloc(pcnt * sizeof (pfnp), - KM_NOSLEEP)) == NULL) { - error = ENOMEM; - goto cleanup; - } - locked->uioa_ppp = (void **)pfnp; - locked->uioa_pfncnt = pcnt; - AS_LOCK_ENTER(as, &as->a_lock, RW_READER); - while (pcnt-- > 0) { - *pfnp++ = hat_getpfnum(as->a_hat, addr); - addr += PAGESIZE; - } - AS_LOCK_EXIT(as, &as->a_lock); - } else { - /* Have a page_t list, save it */ - locked->uioa_ppp = (void **)pages; - locked->uioa_pfncnt = 0; - } - /* Save for as_pageunlock() in uioafini() */ - locked->uioa_base = iov->iov_base; - locked->uioa_len = iov->iov_len; - locked++; - - /* Next iovec_t */ - iov++; - iovcnt--; - } - /* Initialize curret pointer into uioa_locked[] and it's uioa_ppp */ - uioap->uioa_lcur = uioap->uioa_locked; - uioap->uioa_lppp = uioap->uioa_lcur->uioa_ppp; - return (0); - -cleanup: - /* Unlock any previously locked page_t(s) */ - while (locked > uioap->uioa_locked) { - locked--; - as_pageunlock(as, (page_t **)locked->uioa_ppp, - locked->uioa_base, locked->uioa_len, S_WRITE); - } - - /* Last indicate uioa_t still in alloc state */ - uioap->uioa_state = UIOA_ALLOC; - - return (error); -} - -/* - * Finish processing of a uioa_t by cleanup any pending "uioap" actions. - */ -int -uioafini(uio_t *uiop, uioa_t *uioap) -{ - int32_t iovcnt = uiop->uio_iovcnt; - uioa_page_t *locked = uioap->uioa_locked; - struct as *as = ttoproc(curthread)->p_as; - dcopy_handle_t channel; - dcopy_cmd_t cmd; - int ret = 0; - - ASSERT(uioap->uio_extflg & UIO_ASYNC); - - if (!(uioap->uioa_state & (UIOA_ENABLED|UIOA_FINI))) { - /* Must be an active uioa_t */ - return (EINVAL); - } - - channel = uioap->uioa_hwst[UIO_DCOPY_CHANNEL]; - cmd = uioap->uioa_hwst[UIO_DCOPY_CMD]; - - /* XXX - why do we get cmd == NULL sometimes? */ - if (cmd != NULL) { - if (uioap->uioa_state & UIOA_POLL) { - /* Wait for last dcopy() to finish */ - int64_t poll = 1; - int poll_flag = DCOPY_POLL_NOFLAGS; - - do { - if (uioa_maxpoll == 0 || - (uioa_maxpoll > 0 && - poll >= uioa_maxpoll)) { - /* Always block or after maxpoll */ - poll_flag = DCOPY_POLL_BLOCK; - } else { - /* No block, poll */ - poll++; - } - ret = dcopy_cmd_poll(cmd, poll_flag); - } while (ret == DCOPY_PENDING); - - if (ret == DCOPY_COMPLETED) { - /* Poll/block succeeded */ - ret = 0; - } else { - /* Poll/block failed */ - ret = EIO; - } - } - dcopy_cmd_free(&cmd); - } - - dcopy_free(&channel); - - /* Unlock all page(s) iovec_t by iovec_t */ - while (iovcnt-- > 0) { - page_t **pages; - - if (locked->uioa_pfncnt == 0) { - /* A as_pagelock() returned (page_t **) */ - pages = (page_t **)locked->uioa_ppp; - } else { - /* Our pfn_t array */ - pages = NULL; - kmem_free(locked->uioa_ppp, locked->uioa_pfncnt); - } - as_pageunlock(as, pages, locked->uioa_base, locked->uioa_len, - S_WRITE); - - locked++; - } - /* uioa_t->uio_t common struct copy */ - *uiop = *((uio_t *)uioap); - - /* - * Last, reset uioa state to alloc. - * - * Note, we only initialize the state here, all other members - * will be initialized in a subsequent uioainit(). - */ - uioap->uioa_state = UIOA_ALLOC; - - uioap->uioa_hwst[UIO_DCOPY_CMD] = NULL; - uioap->uioa_hwst[UIO_DCOPY_CHANNEL] = NULL; - - return (ret); -} |