On 2026-09-17 10:07, Philip Yang wrote:


On 2026-09-16 21:33, Mukul Joshi wrote:


On 9/16/2026 11:25 AM, Philip Yang wrote:
When one side of UALink nodes reboots, its ring wptr resets to 0 while
the peer keeps a stale value. Read the remote wptr and adopt it as the
local wptr and rptr to resync, before the first message is sent. Either
side can notice first, so do this both when setting up the connection
and when receiving the HELLO from the peer.

On the sdma path, read the wptr in a fence callback because the IB buffer
holding the result is recycled once the fence signals, so reading it
after dma_fence_wait_timeout() is too late. The lsdma path copies
synchronously, so it reads the wptr directly.

Take peer->lock in the callers (amdgpu_ualink_remote_interrupt and
amdgpu_ualink_remote_shootdown) instead of in amdgpu_ualink_send_command,
so the ring->ready check and the send are atomic against a concurrent
ring reset.

Move the rptr refresh and ring-full check out of amdgpu_ualink_send_command()
into amdgpu_ualink_ring_check_space(), so it runs under the caller's
peer->lock before the job is allocated.

On a failed NPA-REQ send, reset the connection like the NPA-RSP timeout path
already does, so the next attempt resyncs the ring wptr.

On connection reset, amdgpu_ualink_reset_peer_rings() only clears
ring->ready, so the writeback address is re-registered on the next send.

v10:
   - Fix the resync missed on the receiving side: after a reboot the peer
     may send HELLO before we set up the connection, so resync the ring
     wptr in amdgpu_ualink_process_hello_msg() too.

v9:
   - Fix the unnecessary connection reset after an app exits: the peer is
     idle here but still busy handling NPA revokes on the remote, so the
     HELLO reset a healthy connection. Only send it if the wptr changed.
   - Resync both rings together under peer->lock, read both remote wptr
     before updating either so a failed read changes nothing.

v8:
   - Fix regression with concurrent import ioctls: do the idle check and
     ring reset in amdgpu_ualink_setup_connection() under conn_state->lock,
     and return -EAGAIN for IN_PROGRESS/PENDING first.
   - Reset the peer rings only, the imp/exp xarray cleanup is not needed to
     resync wptr.

v7:
   - With v6 reboot one node of vPOD test passed on minirack.
   - Use the per-remote imported and exported handle lists for the idle
     check instead of walking the xarrays.
   - Rename amdgpu_ualink_resync_peer_rings() to
     amdgpu_ualink_reset_peer_rings(), it only clears ring->ready.

v6:
   - Check idleness per remote accelerator instead of globally, and reset
     the stale connection at the import ioctl so the peer re-runs the
     HELLO handshake after a reboot.

v5:
   - Resync the ring pointers at the import ioctl when the connection is
     completely idle (no exported or imported BOs), so the first command
     from a new application after a remote reboot/reset succeeds.
   - Put the sdma wptr read fence callback on the stack instead of
     allocating it; it is cancelled on timeout so it never outlives the
     call.

v4:
   - Cancel the sdma fence callback on the wait timeout/failure path so it
     cannot write into the caller's stack after the function returns, and
     free the callback state in one place.

v3:
   - Resync both rings at connection setup instead of on the send path.
   - Set the writeback rptr too, the stale value disagrees with the
     resynced wptr until the remote FW writes it back.

v2:
   - Match the FW change: resync wptr only on the first send or after a
     timeout, instead of checking the remote periodically.

Suggested-by: Felix Kuehling<[email protected]>
Signed-off-by: Philip Yang<[email protected]>
Reviewed-by: Felix Kuehling<[email protected]>
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c | 339 +++++++++++++++++----
  1 file changed, 287 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c
index b2c2650b0149..c0327f6854a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c
@@ -56,6 +56,10 @@ static int amdgpu_ualink_remote_shootdown(struct 
amdgpu_device *adev,
                                          u32 size_in_pages, u32 flush_type);
  static void __amdgpu_ualink_activate_vpod_locked(struct amdgpu_device *adev);
  static bool amdgpu_ualink_vpod_membership_changed(struct amdgpu_device *adev);
+static void amdgpu_ualink_reset_peer_rings(struct amdgpu_device *adev,
+                                          u32 remote_accel_id);
+static int amdgpu_ualink_ring_resync_ptrs(struct amdgpu_device *adev,
+                                         u32 remote_accel_id);
#define STRIP_NPA(addr) \
        (((u64)(addr) & ~AMDGPU_UALINK_NPA_ADDR_GPUID_MASK))
@@ -2282,11 +2286,23 @@ static void amdgpu_ualink_process_hello_msg(struct 
amdgpu_device *adev,
                                                generation_count);
        }
+ /* Peer may have rebooted. */
+       r = amdgpu_ualink_ring_resync_ptrs(adev, sender_acc_id);
+       if (r < 0) {
+               dev_err(adev->dev,
+                       "HELLO: resync sender AccId %u ptrs failed %d\n",
+                       sender_acc_id, r);
+               goto out_set_state;
+       }
+       if (r)
+               amdgpu_ualink_reset_peer_rings(adev, sender_acc_id);
+
        r = amdgpu_ualink_send_hello_ack_msg(adev, sender_acc_id);
        if (r)
                dev_err(adev->dev, "HELLO-ACK: send failed to remote 
AccId:%u\n",
                        sender_acc_id);
+out_set_state:
        mutex_lock(&conn_state->lock);
        if (r) {
                conn_state->state = AMDGPU_UALINK_CONN_NOT_READY;
@@ -2303,6 +2319,14 @@ static void amdgpu_ualink_process_hello_msg(struct 
amdgpu_device *adev,
        mutex_unlock(&conn_state->lock);
  }
+/* True if nothing is exported to, or imported from, this remote accelerator. */
+static bool amdgpu_ualink_peer_idle(struct amdgpu_device *adev, u32 
remote_accel_id)
+{
+       /* Unlocked: a racing import at worst costs one redundant ring resync. 
*/
+       return list_empty(&adev->ualink.imp_handles_list[remote_accel_id]) &&
+              list_empty(&adev->ualink.exp_handles_list[remote_accel_id]);
+}
+
  static int amdgpu_ualink_setup_connection(struct amdgpu_device *adev,
                                          u32 remote_acc_id)
  {
@@ -2324,16 +2348,31 @@ static int amdgpu_ualink_setup_connection(struct 
amdgpu_device *adev,
         * already done by another thread.
         */
        mutex_lock(&conn_state->lock);
-       if (conn_state->state == AMDGPU_UALINK_CONN_ESTABLISHED) {
-               r = 0;
-               goto out;
-       } else if (conn_state->state == AMDGPU_UALINK_CONN_IN_PROGRESS ||
-                  conn_state->state == AMDGPU_UALINK_CONN_PENDING) {
+       if (conn_state->state == AMDGPU_UALINK_CONN_IN_PROGRESS ||
+           conn_state->state == AMDGPU_UALINK_CONN_PENDING) {
                r = -EAGAIN;
                goto out;
        }
+ if (conn_state->state == AMDGPU_UALINK_CONN_ESTABLISHED &&
+           !amdgpu_ualink_peer_idle(adev, remote_acc_id)) {
+               r = 0;
+               goto out;
+       }
+
+       /* Peer is idle or not connected, it may have rebooted. Skip the
+        * handshake if the rings are still in sync, it would reset the remote.
+        */
+       r = amdgpu_ualink_ring_resync_ptrs(adev, remote_acc_id);
+       if (r < 0)
+               goto out;
+       if (!r && conn_state->state == AMDGPU_UALINK_CONN_ESTABLISHED)
+               goto out;
+
+       amdgpu_ualink_reset_peer_rings(adev, remote_acc_id);
+
        conn_state->state = AMDGPU_UALINK_CONN_IN_PROGRESS;
+
        mutex_unlock(&conn_state->lock);
/* Send HELLO message */
@@ -3670,7 +3709,7 @@ static int amdgpu_ualink_do_import_handle(struct 
amdgpu_device *adev,
                dev_warn(adev->dev,
                        "IMPORT: NPA-REQ send failed to remote AccId:%u\n",
                        remote_acc_id);
-               return r;
+               goto reset_conn;
        }
/* Wait for the NPA_RSP to come back */
@@ -5511,6 +5550,34 @@ static void amdgpu_ualink_emit_update_wb_addr(u32 
**cpu_addr_p, u32 wb_data,
  typedef void (*ualink_emit_packet)(u32 **cpu_addr_p, u32 wb, u32 dw0,
                                   u32 dw1, u32 dw2, u32 dw3);
+/*
+ * Refresh rptr from the writeback and check the ring has room for one more
+ * command. The caller must hold the peer lock.
+ *
+ * Return 0 on success or a negative error code.
+ */
+static int amdgpu_ualink_ring_check_space(struct amdgpu_device *adev,
+                                         u32 remote_accel_id,
+                                         struct amdgpu_ualink_ring *ring,
+                                         struct amdgpu_ualink_wb *wb_cpu)
+{
+       ring->rptr = READ_ONCE(wb_cpu->rptr);
+
+       if (WARN_ON_ONCE(ring->rptr > ring->wptr)) {
+               dev_err(adev->dev, "accel_id %u ring overflow wptr 0x%llx rptr 
0x%llx\n",
+                       remote_accel_id, ring->wptr, ring->rptr);
+               return -EFAULT;
+       }
+
+       if ((ring->wptr + 1 - ring->rptr) >= ring->rb_size) {
+               dev_err(adev->dev, "accel_id %u command ring full wptr 0x%llx rptr 
0x%llx\n",
+                       remote_accel_id, ring->wptr, ring->rptr);
+               return -ENOSPC;
+       }
+
+       return 0;
+}
+
  static int amdgpu_ualink_send_command(struct amdgpu_device *adev,
                                      u32 remote_accel_id,
                                      struct amdgpu_ualink_ring *ring,
@@ -5536,6 +5603,10 @@ static int amdgpu_ualink_send_command(struct 
amdgpu_device *adev,
peer = &remote->peer[remote_accel_id]; + r = amdgpu_ualink_ring_check_space(adev, remote_accel_id, ring, wb_cpu);
+       if (r)
+               goto out;
+
        /*
         * 3 sdma copy commands: write data to ring buffer, update wptr, ring 
doorbell
         *
@@ -5552,25 +5623,7 @@ static int amdgpu_ualink_send_command(struct 
amdgpu_device *adev,
                                     ndw * 4, AMDGPU_IB_POOL_IMMEDIATE,
                                     AMDGPU_KERNEL_JOB_ID_TTM_COPY_BUFFER, 
&job);
        if (r)
-               return r;
-
-       mutex_lock(&peer->lock);
-
-       ring->rptr = READ_ONCE(wb_cpu->rptr);
-
-       if (WARN_ON_ONCE(ring->rptr > ring->wptr)) {
-               dev_err(adev->dev, "accel_id %u ring overflow wptr 0x%llx rptr 
0x%llx\n",
-                       remote_accel_id, ring->wptr, ring->rptr);
-               r = -EFAULT;
-               goto unlock_free;
-       }
-
-       if ((ring->wptr + 1 - ring->rptr) >= ring->rb_size) {
-               dev_err(adev->dev, "accel_id %u command ring full wptr 0x%llx rptr 
0x%llx\n",
-                       remote_accel_id, ring->wptr, ring->rptr);
-               r = -ENOSPC;
-               goto unlock_free;
-       }
+               goto out;
ib = &job->ibs[0];
        src = ib->gpu_addr + ndw_copy_cmd * 4;
@@ -5628,12 +5681,11 @@ static int amdgpu_ualink_send_command(struct 
amdgpu_device *adev,
                        dev_dbg(adev->dev,
                                "remote %u lsdma copy failed (r %d), skip completion 
wait\n",
                                remote_accel_id, r);
-                       mutex_unlock(&peer->lock);
                        return r;
                }
goto out_wait_complete;
-        }
+       }
sdma_ring = &adev->sdma.instance[0].ring; @@ -5664,12 +5716,9 @@ static int amdgpu_ualink_send_command(struct amdgpu_device *adev,
        if (r <= 0) {
                dev_dbg(adev->dev, "remote %u sdma fence wait return r %d\n",
                        remote_accel_id, r);
-
                if (r == 0)
                        r = -ETIME;
-
-               mutex_unlock(&peer->lock);
-               return r;
+               goto out;
        }
out_wait_complete:
@@ -5678,21 +5727,15 @@ static int amdgpu_ualink_send_command(struct 
amdgpu_device *adev,
         */
        r = amdgpu_ualink_remote_wait_timeout(adev, remote_accel_id, wb_cpu, 
seq);
- /* increase local copy ring wptr, only if FW not timeout */
-       if (r != -ETIME)
-               ring->wptr++;
-
        /*
-        * Release ring lock after the remote FW handle command completes to
-        * prevent race conditions.
+        * Advance wptr unless the remote timed out, even if the FW returned an
+        * error status. On timeout the caller resets the connection, which
+        * resyncs wptr from the remote in amdgpu_ualink_setup_connection.
         */
-       mutex_unlock(&peer->lock);
-       return r;
-
+       if (r != -ETIME)
+               ring->wptr++;
-unlock_free:
-       mutex_unlock(&peer->lock);
-       amdgpu_job_free(job);
+out:
        dev_dbg(adev->dev, "ret r = %d\n", r);
        return r;
  }
@@ -5732,6 +5775,192 @@ static void amdgpu_ualink_get_wb_addr(struct 
amdgpu_device *adev,
                remote_accel_id, npa + offset);
  }
+struct amdgpu_ualink_wptr_fence_cb {
+       struct dma_fence_cb base;
+       u64 *wptr_cpu;
+       u64 result;
+};
+
+static void amdgpu_ualink_read_wptr_fence_cb(struct dma_fence *fence,
+                                            struct dma_fence_cb *cb)
+{
+       struct amdgpu_ualink_wptr_fence_cb *wptr_cb;
+
+       wptr_cb = container_of(cb, typeof(*wptr_cb), base);
+       wptr_cb->result = *wptr_cb->wptr_cpu;
+}
+
+static int amdgpu_ualink_read_remote_wptr(struct amdgpu_device *adev,
+                                         u32 remote_accel_id,
+                                         struct amdgpu_ualink_ring *ring,
+                                         u64 *wptr)
+{
+       struct amdgpu_ualink_remote *remote = to_remote(adev);
+       struct amdgpu_ualink_peer *peer = &remote->peer[remote_accel_id];
+       struct amdgpu_ualink_wptr_fence_cb wptr_cb = { };
+       struct amdgpu_ring *sdma_ring;
+       struct dma_fence *fence;
+       struct amdgpu_job *job;
+       struct amdgpu_ib *ib;
+       u32 ndw, ndw_copy_cmd;
+       u64 wptr_gpu, *wptr_cpu;
+       int r = 0;
+
Minor nitpick here.

Maybe we should check here that the accelerator state is still active similar to what we are doing in

amdgpu_ualink_send_command().onnection is estiblished,

good point, will add below check, vpod could be deactivated from side-band when app is running.

    /* Refuse sends unless active */
    if (adev->ualink.info->accel_state != AMDGPU_UALINK_ACCEL_STATE_ACTIVE)
        return -ESHUTDOWN;

Are you sure? I was thinking that reading the remote rptr should be done regardless of the accelerator state. This needs to happen before we can make the accelerator active for the first time.

Regards,
  Felix



Regards,
Philip

Other than that, this patch is:

Reviewed-by: Mukul Joshi <[email protected]>

+       *wptr = 0;
+
+       /* 1 sdma copy command to read wptr */
+       ndw_copy_cmd = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
+
+       /* wptr 2 dwords */
+       ndw = ndw_copy_cmd + 2;
+       r = amdgpu_job_alloc_with_ib(adev, &peer->entity, AMDGPU_FENCE_OWNER_VM,
+                                    ndw * 4, AMDGPU_IB_POOL_IMMEDIATE,
+                                    AMDGPU_KERNEL_JOB_ID_TTM_COPY_BUFFER, 
&job);
+       if (r)
+               return r;
+
+       ib = &job->ibs[0];
+       wptr_gpu = ib->gpu_addr + ndw_copy_cmd * 4;
+       wptr_cpu = (u64 *)(ib->ptr + ndw_copy_cmd);
+
+       dev_dbg(adev->dev, "read wptr from remote %u npa gart wptr 0x%llx use 
%s\n",
+               remote_accel_id, ring->wptr_npa_gart,
+               remote->use_lsdma ? "lsdma" : "sdma");
+
+       if (remote->use_lsdma) {
+               r = amdgpu_lsdma_copy_mem(adev, ring->wptr_npa_gart, wptr_gpu, 
8);
+               if (!r)
+                       *wptr = *wptr_cpu;
+               amdgpu_job_free(job);
+               goto out;
+       }
+
+       wptr_cb.wptr_cpu = wptr_cpu;
+
+       amdgpu_emit_copy_buffer(adev, ib, ring->wptr_npa_gart, wptr_gpu, 8, 0);
+
+       sdma_ring = &adev->sdma.instance[0].ring;
+       amdgpu_ring_pad_ib(sdma_ring, ib);
+       WARN_ON(ib->length_dw > ndw_copy_cmd);
+
+       fence = amdgpu_job_submit(job);
+
+       r = dma_fence_add_callback(fence, &wptr_cb.base,
+                                  amdgpu_ualink_read_wptr_fence_cb);
+       if (r == -ENOENT) {
+               /* Fence already signaled; the callback won't run, do it 
inline. */
+               amdgpu_ualink_read_wptr_fence_cb(fence, &wptr_cb.base);
+               r = 0;
+               goto out_put_fence;
+       } else if (r) {
+               /* -EINVAL: NULL fence or func, not expected here. */
+               goto out_put_fence;
+       }
+
+       r = dma_fence_wait_timeout(fence, false, AMDGPU_FENCE_JIFFIES_TIMEOUT);
+       if (r > 0) {
+               r = 0;  /* read wptr successfully */
+               goto out_put_fence;
+       }
+
+       dev_dbg(adev->dev, "remote %u sdma fence wait return r %d\n",
+               remote_accel_id, r);
+
+       if (r == 0)
+               r = -ETIME;
+
+       /*
+        * Timed out: the callback is still armed and wptr_cb is on our stack.
+        * Cancel it so it can't fire after we return and write into the freed
+        * stack frame.
+        */
+       dma_fence_remove_callback(fence, &wptr_cb.base);
+
+out_put_fence:
+       if (!r)
+               *wptr = wptr_cb.result;
+       dma_fence_put(fence);
+
+out:
+       dev_dbg(adev->dev, "remote %u wptr 0x%llx return %d\n",
+               remote_accel_id, *wptr, r);
+       return r;
+}
+
+/**
+ * amdgpu_ualink_ring_resync_ptrs - sync local ring pointers from remote
+ * @adev: amdgpu device pointer
+ * @remote_accel_id: remote accelerator ID
+ *
+ * After a reboot on either side the two ends disagree on wptr. Read the remote
+ * wptr of both peer rings and adopt it as the local wptr and rptr.
+ *
+ * Return 0 if both rings already match, 1 if they were resynced, or a negative
+ * error code if a remote read failed, leaving the rings untouched.
+ */
+static int amdgpu_ualink_ring_resync_ptrs(struct amdgpu_device *adev,
+                                         u32 remote_accel_id)
+{
+       struct amdgpu_ualink_peer *peer = 
&to_remote(adev)->peer[remote_accel_id];
+       struct amdgpu_ualink_wb *int_wb, *tlb_wb;
+       u64 int_wptr, tlb_wptr;
+       int r;
+
+       /* ring->wptr and ring->rptr are owned by the send path. */
+       guard(mutex)(&peer->lock);
+
+       /* Read both before updating either, so a failure changes nothing. */
+       r = amdgpu_ualink_read_remote_wptr(adev, remote_accel_id,
+                                          &peer->interrupt, &int_wptr);
+       if (!r)
+               r = amdgpu_ualink_read_remote_wptr(adev, remote_accel_id,
+                                                  &peer->shootdown, &tlb_wptr);
+       if (r) {
+               dev_dbg(adev->dev, "accel_id %u read remote %u wptr failed 
%d\n",
+                       ualink_accel_id(adev), remote_accel_id, r);
+               return r;
+       }
+
+       if (peer->interrupt.wptr == int_wptr && peer->shootdown.wptr == 
tlb_wptr) {
+               dev_dbg(adev->dev, "accel_id %u wptr 0x%llx 0x%llx is same as remote 
%u\n",
+                       ualink_accel_id(adev), int_wptr, tlb_wptr, 
remote_accel_id);
+               return 0;
+       }
+
+       dev_dbg(adev->dev,
+               "accel_id %u wptr 0x%llx 0x%llx sync to remote %u wptr 0x%llx 
0x%llx\n",
+               ualink_accel_id(adev), peer->interrupt.wptr, 
peer->shootdown.wptr,
+               remote_accel_id, int_wptr, tlb_wptr);
+
+       amdgpu_ualink_get_wb_addr(adev, remote_accel_id, &int_wb, NULL,
+                                 RB_TYPE_REMOTE_INTERRUPT);
+       amdgpu_ualink_get_wb_addr(adev, remote_accel_id, &tlb_wb, NULL,
+                                 RB_TYPE_TLB_INV);
+
+       peer->interrupt.wptr = int_wptr;
+       peer->interrupt.rptr = int_wptr;
+       peer->shootdown.wptr = tlb_wptr;
+       peer->shootdown.rptr = tlb_wptr;
+
+       /* Drop the stale writeback rptr, it disagrees with the resynced wptr. 
*/
+       WRITE_ONCE(int_wb->rptr, int_wptr);
+       WRITE_ONCE(tlb_wb->rptr, tlb_wptr);
+       return 1;
+}
+
+static void amdgpu_ualink_reset_peer_rings(struct amdgpu_device *adev,
+                                          u32 remote_accel_id)
+{
+       struct amdgpu_ualink_peer *peer = 
&to_remote(adev)->peer[remote_accel_id];
+
+       dev_dbg(adev->dev, "remote accel_id %u\n", remote_accel_id);
+
+       guard(mutex)(&peer->lock);
+
+       peer->interrupt.ready = false;
+       peer->shootdown.ready = false;
+}
+
  static int amdgpu_ualink_update_wb_address(struct amdgpu_device *adev,
                                           u32 remote_accel_id, u32 ring_type)
  {
@@ -5794,6 +6023,9 @@ static int amdgpu_ualink_remote_shootdown(struct 
amdgpu_device *adev,
peer = &remote->peer[remote_accel_id];
        ring = &peer->shootdown;
+
+       guard(mutex)(&peer->lock);
+
        if (!ring->ready) {
                dev_dbg(adev->dev, "accel_id %u ring not ready\n", 
remote_accel_id);
                r = amdgpu_ualink_update_wb_address(adev, remote_accel_id,
@@ -5802,11 +6034,11 @@ static int amdgpu_ualink_remote_shootdown(struct 
amdgpu_device *adev,
                        return r;
        }
- r = amdgpu_ualink_send_command(adev, remote_accel_id, ring, ring->wb_cpu,
-                                      amdgpu_ualink_emit_shootdown,
-                                      flush_type, upper_32_bits(addr),
-                                      lower_32_bits(addr), size_in_pages);
-       return r;
+       return amdgpu_ualink_send_command(adev, remote_accel_id, ring,
+                                         ring->wb_cpu,
+                                         amdgpu_ualink_emit_shootdown,
+                                         flush_type, upper_32_bits(addr),
+                                         lower_32_bits(addr), size_in_pages);
  }
/**
@@ -5835,6 +6067,9 @@ static int amdgpu_ualink_remote_interrupt(struct 
amdgpu_device *adev,
peer = &remote->peer[remote_accel_id];
        ring = &peer->interrupt;
+
+       guard(mutex)(&peer->lock);
+
        if (!ring->ready) {
                dev_dbg(adev->dev, "accel_id %u ring not ready\n", 
remote_accel_id);
                r = amdgpu_ualink_update_wb_address(adev, remote_accel_id,
@@ -5843,10 +6078,10 @@ static int amdgpu_ualink_remote_interrupt(struct 
amdgpu_device *adev,
                        return r;
        }
- r = amdgpu_ualink_send_command(adev, remote_accel_id, ring, ring->wb_cpu,
-                                      amdgpu_ualink_emit_interrupt,
-                                      dw0, dw1, dw2, dw3);
-       return r;
+       return amdgpu_ualink_send_command(adev, remote_accel_id, ring,
+                                         ring->wb_cpu,
+                                         amdgpu_ualink_emit_interrupt,
+                                         dw0, dw1, dw2, dw3);
  }
/**

Reply via email to