@@ -428,6 +428,11 @@ static bool strictly_unmovable(unsigned long flags)
428
428
MPOL_MF_STRICT ;
429
429
}
430
430
431
+ struct migration_mpol { /* for alloc_migration_target_by_mpol() */
432
+ struct mempolicy * pol ;
433
+ pgoff_t ilx ;
434
+ };
435
+
431
436
struct queue_pages {
432
437
struct list_head * pagelist ;
433
438
unsigned long flags ;
@@ -1156,8 +1161,9 @@ int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from,
1156
1161
static struct folio * alloc_migration_target_by_mpol (struct folio * src ,
1157
1162
unsigned long private )
1158
1163
{
1159
- struct mempolicy * pol = (struct mempolicy * )private ;
1160
- pgoff_t ilx = 0 ; /* improve on this later */
1164
+ struct migration_mpol * mmpol = (struct migration_mpol * )private ;
1165
+ struct mempolicy * pol = mmpol -> pol ;
1166
+ pgoff_t ilx = mmpol -> ilx ;
1161
1167
struct page * page ;
1162
1168
unsigned int order ;
1163
1169
int nid = numa_node_id ();
@@ -1212,6 +1218,7 @@ static long do_mbind(unsigned long start, unsigned long len,
1212
1218
struct mm_struct * mm = current -> mm ;
1213
1219
struct vm_area_struct * vma , * prev ;
1214
1220
struct vma_iterator vmi ;
1221
+ struct migration_mpol mmpol ;
1215
1222
struct mempolicy * new ;
1216
1223
unsigned long end ;
1217
1224
long err ;
@@ -1284,17 +1291,55 @@ static long do_mbind(unsigned long start, unsigned long len,
1284
1291
}
1285
1292
}
1286
1293
1287
- mmap_write_unlock (mm );
1288
-
1289
1294
if (!err && !list_empty (& pagelist )) {
1290
1295
/* Convert MPOL_DEFAULT's NULL to task or default policy */
1291
1296
if (!new ) {
1292
1297
new = get_task_policy (current );
1293
1298
mpol_get (new );
1294
1299
}
1300
+ mmpol .pol = new ;
1301
+ mmpol .ilx = 0 ;
1302
+
1303
+ /*
1304
+ * In the interleaved case, attempt to allocate on exactly the
1305
+ * targeted nodes, for the first VMA to be migrated; for later
1306
+ * VMAs, the nodes will still be interleaved from the targeted
1307
+ * nodemask, but one by one may be selected differently.
1308
+ */
1309
+ if (new -> mode == MPOL_INTERLEAVE ) {
1310
+ struct page * page ;
1311
+ unsigned int order ;
1312
+ unsigned long addr = - EFAULT ;
1313
+
1314
+ list_for_each_entry (page , & pagelist , lru ) {
1315
+ if (!PageKsm (page ))
1316
+ break ;
1317
+ }
1318
+ if (!list_entry_is_head (page , & pagelist , lru )) {
1319
+ vma_iter_init (& vmi , mm , start );
1320
+ for_each_vma_range (vmi , vma , end ) {
1321
+ addr = page_address_in_vma (page , vma );
1322
+ if (addr != - EFAULT )
1323
+ break ;
1324
+ }
1325
+ }
1326
+ if (addr != - EFAULT ) {
1327
+ order = compound_order (page );
1328
+ /* We already know the pol, but not the ilx */
1329
+ mpol_cond_put (get_vma_policy (vma , addr , order ,
1330
+ & mmpol .ilx ));
1331
+ /* Set base from which to increment by index */
1332
+ mmpol .ilx -= page -> index >> order ;
1333
+ }
1334
+ }
1335
+ }
1336
+
1337
+ mmap_write_unlock (mm );
1338
+
1339
+ if (!err && !list_empty (& pagelist )) {
1295
1340
nr_failed |= migrate_pages (& pagelist ,
1296
1341
alloc_migration_target_by_mpol , NULL ,
1297
- (unsigned long )new , MIGRATE_SYNC ,
1342
+ (unsigned long )& mmpol , MIGRATE_SYNC ,
1298
1343
MR_MEMPOLICY_MBIND , NULL );
1299
1344
}
1300
1345
0 commit comments