@@ -353,18 +353,6 @@ static bool virtio_mem_mb_test_sb_unplugged(struct virtio_mem *vm,
353
353
return find_next_bit (vm -> sb_bitmap , bit + count , bit ) >= bit + count ;
354
354
}
355
355
356
- /*
357
- * Find the first plugged subblock. Returns vm->nb_sb_per_mb in case there is
358
- * none.
359
- */
360
- static int virtio_mem_mb_first_plugged_sb (struct virtio_mem * vm ,
361
- unsigned long mb_id )
362
- {
363
- const int bit = (mb_id - vm -> first_mb_id ) * vm -> nb_sb_per_mb ;
364
-
365
- return find_next_bit (vm -> sb_bitmap , bit + vm -> nb_sb_per_mb , bit ) - bit ;
366
- }
367
-
368
356
/*
369
357
* Find the first unplugged subblock. Returns vm->nb_sb_per_mb in case there is
370
358
* none.
@@ -1016,21 +1004,27 @@ static int virtio_mem_mb_unplug_any_sb(struct virtio_mem *vm,
1016
1004
int sb_id , count ;
1017
1005
int rc ;
1018
1006
1007
+ sb_id = vm -> nb_sb_per_mb - 1 ;
1019
1008
while (* nb_sb ) {
1020
- sb_id = virtio_mem_mb_first_plugged_sb (vm , mb_id );
1021
- if (sb_id >= vm -> nb_sb_per_mb )
1009
+ /* Find the next candidate subblock */
1010
+ while (sb_id >= 0 &&
1011
+ virtio_mem_mb_test_sb_unplugged (vm , mb_id , sb_id , 1 ))
1012
+ sb_id -- ;
1013
+ if (sb_id < 0 )
1022
1014
break ;
1015
+ /* Try to unplug multiple subblocks at a time */
1023
1016
count = 1 ;
1024
- while (count < * nb_sb &&
1025
- sb_id + count < vm -> nb_sb_per_mb &&
1026
- virtio_mem_mb_test_sb_plugged (vm , mb_id , sb_id + count ,
1027
- 1 ))
1017
+ while (count < * nb_sb && sb_id > 0 &&
1018
+ virtio_mem_mb_test_sb_plugged (vm , mb_id , sb_id - 1 , 1 )) {
1028
1019
count ++ ;
1020
+ sb_id -- ;
1021
+ }
1029
1022
1030
1023
rc = virtio_mem_mb_unplug_sb (vm , mb_id , sb_id , count );
1031
1024
if (rc )
1032
1025
return rc ;
1033
1026
* nb_sb -= count ;
1027
+ sb_id -- ;
1034
1028
}
1035
1029
1036
1030
return 0 ;
@@ -1337,12 +1331,12 @@ static int virtio_mem_mb_unplug_any_sb_online(struct virtio_mem *vm,
1337
1331
* we should sense via something like is_mem_section_removable()
1338
1332
* first if it makes sense to go ahead any try to allocate.
1339
1333
*/
1340
- for (sb_id = 0 ; sb_id < vm -> nb_sb_per_mb && * nb_sb ; sb_id ++ ) {
1334
+ for (sb_id = vm -> nb_sb_per_mb - 1 ; sb_id >= 0 && * nb_sb ; sb_id -- ) {
1341
1335
/* Find the next candidate subblock */
1342
- while (sb_id < vm -> nb_sb_per_mb &&
1336
+ while (sb_id >= 0 &&
1343
1337
!virtio_mem_mb_test_sb_plugged (vm , mb_id , sb_id , 1 ))
1344
- sb_id ++ ;
1345
- if (sb_id >= vm -> nb_sb_per_mb )
1338
+ sb_id -- ;
1339
+ if (sb_id < 0 )
1346
1340
break ;
1347
1341
1348
1342
start_pfn = PFN_DOWN (virtio_mem_mb_id_to_phys (mb_id ) +
0 commit comments