Merge drm/drm-next into drm-xe-next
[linux-block.git] / drivers / gpu / drm / xe / xe_gt_pagefault.c
index 59a70d2e0a7a33386fdcfca9cc158919aab1e32c..7ce67c9d30a7b6bcc006c7ddbeb0fc11c722d463 100644 (file)
@@ -282,9 +282,9 @@ static bool get_pagefault(struct pf_queue *pf_queue, struct pagefault *pf)
        bool ret = false;
 
        spin_lock_irq(&pf_queue->lock);
-       if (pf_queue->head != pf_queue->tail) {
+       if (pf_queue->tail != pf_queue->head) {
                desc = (const struct xe_guc_pagefault_desc *)
-                       (pf_queue->data + pf_queue->head);
+                       (pf_queue->data + pf_queue->tail);
 
                pf->fault_level = FIELD_GET(PFD_FAULT_LEVEL, desc->dw0);
                pf->trva_fault = FIELD_GET(XE2_PFD_TRVA_FAULT, desc->dw0);
@@ -302,7 +302,7 @@ static bool get_pagefault(struct pf_queue *pf_queue, struct pagefault *pf)
                pf->page_addr |= FIELD_GET(PFD_VIRTUAL_ADDR_LO, desc->dw2) <<
                        PFD_VIRTUAL_ADDR_LO_SHIFT;
 
-               pf_queue->head = (pf_queue->head + PF_MSG_LEN_DW) %
+               pf_queue->tail = (pf_queue->tail + PF_MSG_LEN_DW) %
                        PF_QUEUE_NUM_DW;
                ret = true;
        }
@@ -315,7 +315,7 @@ static bool pf_queue_full(struct pf_queue *pf_queue)
 {
        lockdep_assert_held(&pf_queue->lock);
 
-       return CIRC_SPACE(pf_queue->tail, pf_queue->head, PF_QUEUE_NUM_DW) <=
+       return CIRC_SPACE(pf_queue->head, pf_queue->tail, PF_QUEUE_NUM_DW) <=
                PF_MSG_LEN_DW;
 }
 
@@ -328,6 +328,11 @@ int xe_guc_pagefault_handler(struct xe_guc *guc, u32 *msg, u32 len)
        u32 asid;
        bool full;
 
+       /*
+        * The below logic doesn't work unless PF_QUEUE_NUM_DW % PF_MSG_LEN_DW == 0
+        */
+       BUILD_BUG_ON(PF_QUEUE_NUM_DW % PF_MSG_LEN_DW);
+
        if (unlikely(len != PF_MSG_LEN_DW))
                return -EPROTO;
 
@@ -337,8 +342,8 @@ int xe_guc_pagefault_handler(struct xe_guc *guc, u32 *msg, u32 len)
        spin_lock_irqsave(&pf_queue->lock, flags);
        full = pf_queue_full(pf_queue);
        if (!full) {
-               memcpy(pf_queue->data + pf_queue->tail, msg, len * sizeof(u32));
-               pf_queue->tail = (pf_queue->tail + len) % PF_QUEUE_NUM_DW;
+               memcpy(pf_queue->data + pf_queue->head, msg, len * sizeof(u32));
+               pf_queue->head = (pf_queue->head + len) % PF_QUEUE_NUM_DW;
                queue_work(gt->usm.pf_wq, &pf_queue->worker);
        } else {
                drm_warn(&xe->drm, "PF Queue full, shouldn't be possible");
@@ -384,7 +389,7 @@ static void pf_queue_work_func(struct work_struct *w)
                send_pagefault_reply(&gt->uc.guc, &reply);
 
                if (time_after(jiffies, threshold) &&
-                   pf_queue->head != pf_queue->tail) {
+                   pf_queue->tail != pf_queue->head) {
                        queue_work(gt->usm.pf_wq, w);
                        break;
                }
@@ -559,9 +564,9 @@ static bool get_acc(struct acc_queue *acc_queue, struct acc *acc)
        bool ret = false;
 
        spin_lock(&acc_queue->lock);
-       if (acc_queue->head != acc_queue->tail) {
+       if (acc_queue->tail != acc_queue->head) {
                desc = (const struct xe_guc_acc_desc *)
-                       (acc_queue->data + acc_queue->head);
+                       (acc_queue->data + acc_queue->tail);
 
                acc->granularity = FIELD_GET(ACC_GRANULARITY, desc->dw2);
                acc->sub_granularity = FIELD_GET(ACC_SUBG_HI, desc->dw1) << 31 |
@@ -574,7 +579,7 @@ static bool get_acc(struct acc_queue *acc_queue, struct acc *acc)
                acc->va_range_base = make_u64(desc->dw3 & ACC_VIRTUAL_ADDR_RANGE_HI,
                                              desc->dw2 & ACC_VIRTUAL_ADDR_RANGE_LO);
 
-               acc_queue->head = (acc_queue->head + ACC_MSG_LEN_DW) %
+               acc_queue->tail = (acc_queue->tail + ACC_MSG_LEN_DW) %
                                  ACC_QUEUE_NUM_DW;
                ret = true;
        }
@@ -602,7 +607,7 @@ static void acc_queue_work_func(struct work_struct *w)
                }
 
                if (time_after(jiffies, threshold) &&
-                   acc_queue->head != acc_queue->tail) {
+                   acc_queue->tail != acc_queue->head) {
                        queue_work(gt->usm.acc_wq, w);
                        break;
                }
@@ -613,7 +618,7 @@ static bool acc_queue_full(struct acc_queue *acc_queue)
 {
        lockdep_assert_held(&acc_queue->lock);
 
-       return CIRC_SPACE(acc_queue->tail, acc_queue->head, ACC_QUEUE_NUM_DW) <=
+       return CIRC_SPACE(acc_queue->head, acc_queue->tail, ACC_QUEUE_NUM_DW) <=
                ACC_MSG_LEN_DW;
 }
 
@@ -624,6 +629,11 @@ int xe_guc_access_counter_notify_handler(struct xe_guc *guc, u32 *msg, u32 len)
        u32 asid;
        bool full;
 
+       /*
+        * The below logic doesn't work unless ACC_QUEUE_NUM_DW % ACC_MSG_LEN_DW == 0
+        */
+       BUILD_BUG_ON(ACC_QUEUE_NUM_DW % ACC_MSG_LEN_DW);
+
        if (unlikely(len != ACC_MSG_LEN_DW))
                return -EPROTO;
 
@@ -633,9 +643,9 @@ int xe_guc_access_counter_notify_handler(struct xe_guc *guc, u32 *msg, u32 len)
        spin_lock(&acc_queue->lock);
        full = acc_queue_full(acc_queue);
        if (!full) {
-               memcpy(acc_queue->data + acc_queue->tail, msg,
+               memcpy(acc_queue->data + acc_queue->head, msg,
                       len * sizeof(u32));
-               acc_queue->tail = (acc_queue->tail + len) % ACC_QUEUE_NUM_DW;
+               acc_queue->head = (acc_queue->head + len) % ACC_QUEUE_NUM_DW;
                queue_work(gt->usm.acc_wq, &acc_queue->worker);
        } else {
                drm_warn(&gt_to_xe(gt)->drm, "ACC Queue full, dropping ACC");