File tree Expand file tree Collapse file tree 1 file changed +15
-3
lines changed Expand file tree Collapse file tree 1 file changed +15
-3
lines changed Original file line number Diff line number Diff line change @@ -154,11 +154,23 @@ static int __page_handle_poison(struct page *page)
154
154
{
155
155
int ret ;
156
156
157
- zone_pcp_disable (page_zone (page ));
157
+ /*
158
+ * zone_pcp_disable() can't be used here. It will
159
+ * hold pcp_batch_high_lock and dissolve_free_huge_page() might hold
160
+ * cpu_hotplug_lock via static_key_slow_dec() when hugetlb vmemmap
161
+ * optimization is enabled. This will break current lock dependency
162
+ * chain and leads to deadlock.
163
+ * Disabling pcp before dissolving the page was a deterministic
164
+ * approach because we made sure that those pages cannot end up in any
165
+ * PCP list. Draining PCP lists expels those pages to the buddy system,
166
+ * but nothing guarantees that those pages do not get back to a PCP
167
+ * queue if we need to refill those.
168
+ */
158
169
ret = dissolve_free_huge_page (page );
159
- if (!ret )
170
+ if (!ret ) {
171
+ drain_all_pages (page_zone (page ));
160
172
ret = take_page_off_buddy (page );
161
- zone_pcp_enable ( page_zone ( page ));
173
+ }
162
174
163
175
return ret ;
164
176
}
You can’t perform that action at this time.
0 commit comments