/* * Copyright (C) 2007 Ben Skeggs. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
*/
if (intr && signal_pending(current)) {
ret = -ERESTARTSYS; break;
}
}
__set_current_state(TASK_RUNNING); return ret;
}
int
nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr)
{ long ret;
if (!lazy) return nouveau_fence_wait_busy(fence, intr);
ret = dma_fence_wait_timeout(&fence->base, intr, 15 * HZ); if (ret < 0) return ret; elseif (!ret) return -EBUSY; else return0;
}
int
nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool exclusive, bool intr)
{ struct nouveau_fence_chan *fctx = chan->fence; struct dma_resv *resv = nvbo->bo.base.resv; int i, ret;
ret = dma_resv_reserve_fences(resv, 1); if (ret) return ret;
/* Waiting for the writes first causes performance regressions * under some circumstances. So manually wait for the reads first.
*/ for (i = 0; i < 2; ++i) { struct dma_resv_iter cursor; struct dma_fence *fence;
/* * In an ideal world, read would not assume the channel context is still alive. * This function may be called from another device, running into free memory as a * result. The drm node should still be there, so we can derive the index from * the fence context.
*/ staticbool nouveau_fence_is_signaled(struct dma_fence *f)
{ struct nouveau_fence *fence = to_nouveau_fence(f); struct nouveau_fence_chan *fctx = nouveau_fctx(fence); struct nouveau_channel *chan; bool ret = false;
rcu_read_lock();
chan = rcu_dereference(fence->channel); if (chan)
ret = (int)(fctx->read(chan) - fence->base.seqno) >= 0;
rcu_read_unlock();
/* * caller should have a reference on the fence, * else fence could get freed here
*/
WARN_ON(kref_read(&fence->base.refcount) <= 1);
/* * This needs uevents to work correctly, but dma_fence_add_callback relies on * being able to enable signaling. It will still get signaled eventually, * just not right away.
*/ if (nouveau_fence_is_signaled(f)) {
list_del(&fence->head);
if (!fctx->notify_ref++)
nvif_event_allow(&fctx->event);
ret = nouveau_fence_no_signaling(f); if (ret)
set_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags); elseif (!--fctx->notify_ref)
nvif_event_block(&fctx->event);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.