--- ./source/private_module/reloc/reloc_v2/relocation_level.c	2018-04-12 07:22:49.000000000 +0000
+++ ./source/private_module/reloc/reloc_v2/relocation_level.c.hotpatch	2022-04-14 09:24:57.000000000 +0000
@@ -24,18 +24,18 @@
 /*****************************************************************/
 
 uint64_t g_startLevelLimit = 0;//* Ƿʹ չʹ*/
-
-
+#define LEVEL_MATCH_CKG_MAX_NUM_PER_LOOP 10000
+#define LEVEL_NEED_DELAY_MATCH_FLAG 1234ULL
+#ifdef _DEBUG
+#define RELOC_DEBUGLOG(LogID, ...) DBG_LogInfo((LogID), __VA_ARGS__)
+#else
+#define RELOC_DEBUGLOG(LogID, ...) RELOC_PRINT_LIMIT_PERIOD(RELOCLOG_RES_LACK_INTERVAL, RELOCLOG_CTRL_COUNT, DBG_LOG_INFO, (LogID), __VA_ARGS__)
+#endif
 /*****************************************************************/
+uint64_t levelGetContextPriv(CONTEXT_S *context, int index);
+void levelSetContextPriv(CONTEXT_S *context, uint64_t index, uint64_t value);
+
 
-/**************************************************************************
-     :  عϢ
- :  task -- ع
- :  
- ֵ  :  REUTNR_OK -- ɹ
-            -- ʧ
-     :  
-**************************************************************************/ 
 RELOC_PRIVATE void setLevelTaskProcess(RELOCATION_TASK_S *levelTask, CKG_FLAG_S *ckgFlag)
 {
     LEVEL_PRIVATE_S *levelPrivate = NULL;
@@ -943,27 +943,27 @@
     int32_t iRet = RETURN_ERROR;
     CHECK_NEED_LEVEL_S* checkPrivate = NULL;
     CONTEXT_S* parentContext = NULL;
- 
     parentContext = (CONTEXT_S*)procParam;
-
     checkPrivate = (CHECK_NEED_LEVEL_S*)getData(parentContext);
-
     /*rootckgҪ*/
     if (TEST_ROOT_CKG_ID((ckgid_t)GET_CKG_OBJ_CKG_ID(ckgObjId)))
     {
         return RETURN_OK;
     }
-
     checkPrivate->ckgNum++;
 
     iRet = selectCkgDisks(checkPrivate->poolId, ckgObjId, ckgInfo, checkPrivate->newDiskIds);
     if (RETURN_OK != iRet)
-    {
+    {   // ʹcontext˽ֶΣpriv[0]lastCkgObjIdpriv[1]ӳٱǣforeachXXͽѭȻӳ100msϴελüforeach
+        if (checkPrivate->ckgNum > LEVEL_MATCH_CKG_MAX_NUM_PER_LOOP) {
+            RELOC_DEBUGLOG(NO_LOGID, "Level match ckg exceed %u and need delay, pool(%u), ckgId(0x%llx), ckgNum(%u).", LEVEL_MATCH_CKG_MAX_NUM_PER_LOOP, checkPrivate->poolId, ckgObjId, checkPrivate->ckgNum);  
+            levelSetContextPriv(parentContext, 0ULL, ckgObjId); 
+            levelSetContextPriv(parentContext, 1ULL, LEVEL_NEED_DELAY_MATCH_FLAG);
+            return RETURN_NEED_LEVEL;
+        }
         return RETURN_OK;
     }
-
     checkPrivate->result = RETURN_NEED_LEVEL;
-
     return RETURN_NEED_LEVEL;
 }
 
@@ -975,33 +975,33 @@
      :  
 **************************************************************************/
 
-RELOC_PRIVATE int32_t checkEachCkgNeedLevel(CONTEXT_S* ckgContext)
-{
+RELOC_PRIVATE int32_t checkEachCkgNeedLevel(CONTEXT_S* ckgContext) {
     CHECK_NEED_LEVEL_S* checkPrivate = (CHECK_NEED_LEVEL_S*)getData(ckgContext);
-
-    foreachDiskPoolCkgs(checkPrivate->poolId, checkPrivate->tierId, INVALID_VALUE64,
+    uint64_t startCkgObjId = levelGetContextPriv(ckgContext, 0);
+    if (startCkgObjId == 0) { startCkgObjId = INVALID_VALUE64; } 
+    levelSetContextPriv(ckgContext, 1ULL, 0ULL);  checkPrivate->ckgNum = 0;
+    foreachDiskPoolCkgs(checkPrivate->poolId, checkPrivate->tierId, startCkgObjId,
                         needLevelCkgMatch, ckgContext, &checkPrivate->result, ckgContext);
-
     return CONTEXT_PENDING;
 }
 
 RELOC_PRIVATE int32_t checkNeedLevelFinish(CONTEXT_S* ckgContext)
 {
     CHECK_NEED_LEVEL_S* checkPrivate = (CHECK_NEED_LEVEL_S*)getData(ckgContext);
-    UNREFERENCE_PARAM(ckgContext);
-
-
-    if (checkPrivate->result == RETURN_NEED_LEVEL)
-    {
+    uint64_t flag = levelGetContextPriv(ckgContext, 1);  
+    if (flag == LEVEL_NEED_DELAY_MATCH_FLAG) { 
+        RELOC_DEBUGLOG(NO_LOGID, "Level need delay match, pool(%u) ckgNum(%u) ret(%d).", checkPrivate->poolId, checkPrivate->ckgNum, checkPrivate->result);
+        gotoStep(ckgContext, CHECK_NEED_LEVEL_EACH_CKG);
+        return CONTEXT_CONTINUE_SLOW;
+    }
+    if (checkPrivate->result == RETURN_NEED_LEVEL) {
         checkPrivate->callback(checkPrivate->context, TRUE);
     }
-    else
-    {
+    else {
     	DBG_LogInfo(LEVEL_LOG_0002, "level pool(%u) tierId(%u) NO ckg need level.", 
                 checkPrivate->poolId, checkPrivate->tierId);
         checkPrivate->callback(checkPrivate->context, FALSE);
     }
-
     return CONTEXT_FINISH;
 }
 
@@ -1049,3 +1049,19 @@
     executeContext(checkContext);
 }
 
+uint64_t levelGetContextPriv(CONTEXT_S *context, int index)
+{
+    uint64_t *priv = NULL;
+    priv = (uint64_t *)getContextPriv(context);
+    return priv[index];
+}
+
+void levelSetContextPriv(CONTEXT_S *context, uint64_t index, uint64_t value)
+{
+    uint64_t *priv = NULL;
+    priv = (uint64_t *)getContextPriv(context);
+    priv[index] = value;
+    return;
+}
+
+
