uint32_t filter_param)
 {
        int retval = 0;
+       struct mqd_manager *mqd_mgr;
 
        if (!dqm->sched_running)
                return 0;
                return retval;
        }
 
+       /* In the current MEC firmware implementation, if compute queue
+        * doesn't response to the preemption request in time, HIQ will
+        * abandon the unmap request without returning any timeout error
+        * to driver. Instead, MEC firmware will log the doorbell of the
+        * unresponding compute queue to HIQ.MQD.queue_doorbell_id fields.
+        * To make sure the queue unmap was successful, driver need to
+        * check those fields
+        */
+       mqd_mgr = dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ];
+       if (mqd_mgr->read_doorbell_id(dqm->packets.priv_queue->queue->mqd)) {
+               pr_err("HIQ MQD's queue_doorbell_id0 is not 0, Queue preemption time out\n");
+               while (halt_if_hws_hang)
+                       schedule();
+               return -ETIME;
+       }
+
        pm_release_ib(&dqm->packets);
        dqm->active_runlist = false;
 
 
 #if defined(CONFIG_DEBUG_FS)
        int     (*debugfs_show_mqd)(struct seq_file *m, void *data);
 #endif
+       uint32_t (*read_doorbell_id)(void *mqd);
 
        struct mutex    mqd_mutex;
        struct kfd_dev  *dev;
 
        __update_mqd(mm, mqd, q, 1);
 }
 
+static uint32_t read_doorbell_id(void *mqd)
+{
+       struct cik_mqd *m = (struct cik_mqd *)mqd;
+
+       return m->queue_doorbell_id0;
+}
+
 static void update_mqd_hawaii(struct mqd_manager *mm, void *mqd,
                        struct queue_properties *q)
 {
 #if defined(CONFIG_DEBUG_FS)
                mqd->debugfs_show_mqd = debugfs_show_mqd;
 #endif
+               mqd->read_doorbell_id = read_doorbell_id;
                break;
        case KFD_MQD_TYPE_DIQ:
                mqd->allocate_mqd = allocate_mqd;
 
        q->is_active = QUEUE_IS_ACTIVE(*q);
 }
 
+static uint32_t read_doorbell_id(void *mqd)
+{
+       struct v10_compute_mqd *m = (struct v10_compute_mqd *)mqd;
+
+       return m->queue_doorbell_id0;
+}
+
 static int destroy_mqd(struct mqd_manager *mm, void *mqd,
                       enum kfd_preempt_type type,
                       unsigned int timeout, uint32_t pipe_id,
 #if defined(CONFIG_DEBUG_FS)
                mqd->debugfs_show_mqd = debugfs_show_mqd;
 #endif
+               mqd->read_doorbell_id = read_doorbell_id;
                pr_debug("%s@%i\n", __func__, __LINE__);
                break;
        case KFD_MQD_TYPE_DIQ:
 
 }
 
 
+static uint32_t read_doorbell_id(void *mqd)
+{
+       struct v9_mqd *m = (struct v9_mqd *)mqd;
+
+       return m->queue_doorbell_id0;
+}
+
 static int destroy_mqd(struct mqd_manager *mm, void *mqd,
                        enum kfd_preempt_type type,
                        unsigned int timeout, uint32_t pipe_id,
 #if defined(CONFIG_DEBUG_FS)
                mqd->debugfs_show_mqd = debugfs_show_mqd;
 #endif
+               mqd->read_doorbell_id = read_doorbell_id;
                break;
        case KFD_MQD_TYPE_DIQ:
                mqd->allocate_mqd = allocate_mqd;
 
        __update_mqd(mm, mqd, q, MTYPE_CC, 1);
 }
 
+static uint32_t read_doorbell_id(void *mqd)
+{
+       struct vi_mqd *m = (struct vi_mqd *)mqd;
+
+       return m->queue_doorbell_id0;
+}
+
 static void update_mqd_tonga(struct mqd_manager *mm, void *mqd,
                        struct queue_properties *q)
 {
 #if defined(CONFIG_DEBUG_FS)
                mqd->debugfs_show_mqd = debugfs_show_mqd;
 #endif
+               mqd->read_doorbell_id = read_doorbell_id;
                break;
        case KFD_MQD_TYPE_DIQ:
                mqd->allocate_mqd = allocate_mqd;
 
        uint32_t reserved60;
        uint32_t reserved61;
        uint32_t reserved62;
-       uint32_t reserved63;
-       uint32_t reserved64;
-       uint32_t reserved65;
-       uint32_t reserved66;
-       uint32_t reserved67;
-       uint32_t reserved68;
-       uint32_t reserved69;
-       uint32_t reserved70;
-       uint32_t reserved71;
-       uint32_t reserved72;
-       uint32_t reserved73;
-       uint32_t reserved74;
-       uint32_t reserved75;
-       uint32_t reserved76;
-       uint32_t reserved77;
-       uint32_t reserved78;
+       uint32_t queue_doorbell_id0;
+       uint32_t queue_doorbell_id1;
+       uint32_t queue_doorbell_id2;
+       uint32_t queue_doorbell_id3;
+       uint32_t queue_doorbell_id4;
+       uint32_t queue_doorbell_id5;
+       uint32_t queue_doorbell_id6;
+       uint32_t queue_doorbell_id7;
+       uint32_t queue_doorbell_id8;
+       uint32_t queue_doorbell_id9;
+       uint32_t queue_doorbell_id10;
+       uint32_t queue_doorbell_id11;
+       uint32_t queue_doorbell_id12;
+       uint32_t queue_doorbell_id13;
+       uint32_t queue_doorbell_id14;
+       uint32_t queue_doorbell_id15;
        uint32_t reserved_t[256];
 };