.. include:: ../disclaimer-zh_CN.rst :Original: Documentation/core-api/memory-hotplug.rst :翻译: å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn> :æ ¡è¯‘: å´æƒ³æˆ Wu XiangCheng <bobwxc@email.cn> .. _cn_core-api_memory-hotplug: ========== 内å˜çƒæ’æ‹” ========== 内å˜çƒæ‹”æ’事件通知器 ==================== çƒæ’拔事件被å‘é€åˆ°ä¸€ä¸ªé€šçŸ¥é˜Ÿåˆ—ä¸ã€‚ 在 ``include/linux/memory.h`` ä¸å®šä¹‰äº†å…ç§ç±»åž‹çš„通知: MEM_GOING_ONLINE 在新内å˜å¯ç”¨ä¹‹å‰ç”Ÿæˆï¼Œä»¥ä¾¿èƒ½å¤Ÿä¸ºå系统处ç†å†…å˜åšå‡†å¤‡ã€‚页é¢åˆ†é…器ä»ç„¶æ— 法从新 的内å˜ä¸è¿›è¡Œåˆ†é…。 MEM_CANCEL_ONLINE 如果MEM_GOING_ONLINE失败,则生æˆã€‚ MEM_ONLINE 当内å˜æˆåŠŸä¸Šçº¿æ—¶äº§ç”Ÿã€‚回调å¯ä»¥ä»Žæ–°çš„内å˜ä¸åˆ†é…页é¢ã€‚ MEM_GOING_OFFLINE 在开始对内å˜è¿›è¡Œä¸‹çº¿å¤„ç†æ—¶ç”Ÿæˆã€‚从内å˜ä¸çš„分é…ä¸å†å¯èƒ½ï¼Œä½†æ˜¯ä¸€äº›è¦ä¸‹çº¿çš„å†…å˜ ä»ç„¶åœ¨ä½¿ç”¨ã€‚回调å¯ä»¥ç”¨æ¥é‡Šæ”¾ä¸€ä¸ªå系统在指定内å˜å—ä¸å·²çŸ¥çš„内å˜ã€‚ MEM_CANCEL_OFFLINE 如果MEM_GOING_OFFLINE失败,则生æˆã€‚æ¥è‡ªæˆ‘们试图离线的内å˜å—ä¸çš„内å˜åˆå¯ä»¥ä½¿ 用了。 MEM_OFFLINE 在内å˜ä¸‹çº¿å®ŒæˆåŽç”Ÿæˆã€‚ å¯ä»¥é€šè¿‡è°ƒç”¨å¦‚下函数æ¥æ³¨å†Œä¸€ä¸ªå›žè°ƒç¨‹åº: hotplug_memory_notifier(callback_func, priority) 优先级数值较高的回调函数在数值较低的回调函数之å‰è¢«è°ƒç”¨ã€‚ 一个回调函数必须有以下原型:: int callback_func( struct notifier_block *self, unsigned long action, void *arg); 回调函数的第一个å‚数(self)是指å‘回调函数本身的通知器链å—çš„ä¸€ä¸ªæŒ‡é’ˆã€‚ç¬¬äºŒä¸ªå‚ æ•°ï¼ˆaction)是上述的事件类型之一。第三个å‚数(argï¼‰ä¼ é€’ä¸€ä¸ªæŒ‡å‘ memory_notify结构体的指针:: struct memory_notify { unsigned long start_pfn; unsigned long nr_pages; int status_change_nid_normal; int status_change_nid; } - start_pfn是在线/离线内å˜çš„start_pfn。 - nr_pages是在线/离线内å˜çš„页数。 - status_change_nid_normal是当nodemaskçš„N_NORMAL_MEMORY被设置/清除时设置节 点id,如果是-1,则nodemask状æ€ä¸æ”¹å˜ã€‚ - status_change_nid是当nodemaskçš„N_MEMORY被(将)设置/清除时设置的节点id。这 æ„味ç€ä¸€ä¸ªæ–°çš„(没上线的)节点通过è”机获得新的内å˜ï¼Œè€Œä¸€ä¸ªèŠ‚点失去了所有的内 å˜ã€‚如果这个值为-1,那么nodemask的状æ€å°±ä¸ä¼šæ”¹å˜ã€‚ 如果 status_changed_nid* >= 0,回调应该在必è¦æ—¶ä¸ºèŠ‚点创建/丢弃结构体。 回调程åºåº”返回 ``include/linux/notifier.h`` ä¸å®šä¹‰çš„NOTIFY_DONE, NOTIFY_OK, NOTIFY_BAD, NOTIFY_STOPä¸çš„一个值。 NOTIFY_DONEå’ŒNOTIFY_OK对进一æ¥å¤„ç†æ²¡æœ‰å½±å“。 NOTIFY_BAD是作为对MEM_GOING_ONLINEã€MEM_GOING_OFFLINEã€MEM_ONLINE或MEM_OFFLINE 动作的回应,用于å–消çƒæ’拔。它åœæ¢å¯¹é€šçŸ¥é˜Ÿåˆ—的进一æ¥å¤„ç†ã€‚ NOTIFY_STOPåœæ¢å¯¹é€šçŸ¥é˜Ÿåˆ—的进一æ¥å¤„ç†ã€‚ å†…éƒ¨é” ====== å½“æ·»åŠ /åˆ é™¤ä½¿ç”¨å†…å˜å—设备(å³æ™®é€šRAM)的内å˜æ—¶ï¼Œdevice_hotplug_lock应该被ä¿æŒ 为: - 针对在线/离线请求进行åŒæ¥ï¼ˆä¾‹å¦‚,通过sysfsï¼‰ã€‚è¿™æ ·ä¸€æ¥ï¼Œå†…å˜å—设备åªæœ‰åœ¨å†…å˜ è¢«å®Œå…¨æ·»åŠ åŽæ‰èƒ½è¢«ç”¨æˆ·ç©ºé—´è®¿é—®ï¼ˆ.online/.stateå±žæ€§ï¼‰ã€‚è€Œåœ¨åˆ é™¤å†…å˜æ—¶ï¼Œæˆ‘们知 é“没有人在临界区。 - 与CPUçƒæ‹”æ’或类似æ“作åŒæ¥ï¼ˆä¾‹å¦‚ACPIå’ŒPPC相关æ“作) ç‰¹åˆ«æ˜¯ï¼Œåœ¨æ·»åŠ å†…å˜å’Œç”¨æˆ·ç©ºé—´è¯•å›¾ä»¥æ¯”预期更快的速度上线该内å˜æ—¶ï¼Œæœ‰å¯èƒ½å‡ºçŽ°é”å转, 使用device_hotplug_lockå¯ä»¥é¿å…æ¤æƒ…况: - device_online()将首先接å—device_lock(),然åŽæ˜¯mem_hotplug_lock。 - add_memory_resource()将首先使用mem_hotplug_lock,然åŽæ˜¯device_lock()(在创 建设备时,在bus_add_device()期间)。 由于在使用device_lock()之å‰ï¼Œè®¾å¤‡å¯¹ç”¨æˆ·ç©ºé—´æ˜¯å¯è§çš„,这å¯èƒ½å¯¼è‡´é”çš„å转。 内å˜çš„上线/下线应该通过device_online()/device_offline()完æˆâ€”———确ä¿å®ƒä¸Žé€šè¿‡ sysfs进行的æ“作æ£ç¡®åŒæ¥ã€‚建议æŒæœ‰device_hotplug_lock(例如,ä¿æŠ¤online_type)。 å½“æ·»åŠ /åˆ é™¤/上线/下线内å˜æˆ–è€…æ·»åŠ /åˆ é™¤å¼‚æž„æˆ–è®¾å¤‡å†…å˜æ—¶ï¼Œæˆ‘们应该始终æŒæœ‰å†™æ¨¡å¼çš„ mem_hotplug_lock,以åºåˆ—化内å˜çƒæ’拔(例如访问全局/区域å˜é‡ï¼‰ã€‚ æ¤å¤–,mem_hotplug_lock(与device_hotplug_lock相å)在读å–模å¼ä¸‹å…许一个相当 有效的get_online_mems/put_online_mems实现,所以访问内å˜çš„代ç å¯ä»¥é˜²æ¢è¯¥å†…å˜ æ¶ˆå¤±ã€‚