summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/move.c
diff options
context:
space:
mode:
authordm120769 <none@none>2008-04-25 20:19:02 -0700
committerdm120769 <none@none>2008-04-25 20:19:02 -0700
commitc6c65e5445ba6bc005f3da488bddd36494d26e65 (patch)
treeb769322e7f726d81a4e2a3c7ce53ba85d28c2ecc /usr/src/uts/common/os/move.c
parent0cfb4e8b28ab16b0cb224619362e8135673714c3 (diff)
downloadillumos-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.c384
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);
-}