Commit 96b7f34143c2c823a6a750fcb758fc66c44945d2

Authored by Paul Jackson
Committed by Linus Torvalds
1 parent 10cef60295

[PATCH] cpuset: better bitmap remap defaults

Fix the default behaviour for the remap operators in bitmap, cpumask and
nodemask.

As previously submitted, the pair of masks <A, B> defined a map of the
positions of the set bits in A to the corresponding bits in B.  This is still
true.

The issue is how to map the other positions, corresponding to the unset (0)
bits in A.  As previously submitted, they were all mapped to the first set bit
position in B, a constant map.

When I tried to code per-vma mempolicy rebinding using these remap operators,
I realized this was wrong.

This patch changes the default to map all the unset bit positions in A to the
same positions in B, the identity map.

For example, if A has bits 4-7 set, and B has bits 9-12 set, then the map
defined by the pair <A, B> maps each bit position in the first 32 bits as
follows:

	0 ==> 0
	  ...
	3 ==> 3
	4 ==> 9
	  ...
	7 ==> 12
	8 ==> 8
	9 ==> 9
	  ...
	31 ==> 31

This now corresponds to the typical behaviour desired when migrating pages and
policies from one cpuset to another.

The pages on nodes within the original cpuset, and the references in memory
policies to nodes within the original cpuset, are migrated to the
corresponding cpuset-relative nodes in the destination cpuset.  Other pages
and node references are left untouched.

Signed-off-by: Paul Jackson <pj@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 44 additions and 45 deletions Side-by-side Diff

... ... @@ -519,7 +519,7 @@
519 519 *
520 520 * Map the bit at position @pos in @buf (of length @bits) to the
521 521 * ordinal of which set bit it is. If it is not set or if @pos
522   - * is not a valid bit position, map to zero (0).
  522 + * is not a valid bit position, map to -1.
523 523 *
524 524 * If for example, just bits 4 through 7 are set in @buf, then @pos
525 525 * values 4 through 7 will get mapped to 0 through 3, respectively,
526 526  
527 527  
528 528  
... ... @@ -531,18 +531,19 @@
531 531 */
532 532 static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
533 533 {
534   - int ord = 0;
  534 + int i, ord;
535 535  
536   - if (pos >= 0 && pos < bits) {
537   - int i;
  536 + if (pos < 0 || pos >= bits || !test_bit(pos, buf))
  537 + return -1;
538 538  
539   - for (i = find_first_bit(buf, bits);
540   - i < pos;
541   - i = find_next_bit(buf, bits, i + 1))
542   - ord++;
543   - if (i > pos)
544   - ord = 0;
  539 + i = find_first_bit(buf, bits);
  540 + ord = 0;
  541 + while (i < pos) {
  542 + i = find_next_bit(buf, bits, i + 1);
  543 + ord++;
545 544 }
  545 + BUG_ON(i != pos);
  546 +
546 547 return ord;
547 548 }
548 549  
549 550  
... ... @@ -553,11 +554,12 @@
553 554 * @bits: number of valid bit positions in @buf
554 555 *
555 556 * Map the ordinal offset of bit @ord in @buf to its position in @buf.
556   - * If @ord is not the ordinal offset of a set bit in @buf, map to zero (0).
  557 + * Value of @ord should be in range 0 <= @ord < weight(buf), else
  558 + * results are undefined.
557 559 *
558 560 * If for example, just bits 4 through 7 are set in @buf, then @ord
559 561 * values 0 through 3 will get mapped to 4 through 7, respectively,
560   - * and all other @ord valuds will get mapped to 0. When @ord value 3
  562 + * and all other @ord values return undefined values. When @ord value 3
561 563 * gets mapped to (returns) @pos value 7 in this example, that means
562 564 * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
563 565 *
564 566  
... ... @@ -583,8 +585,8 @@
583 585  
584 586 /**
585 587 * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
586   - * @src: subset to be remapped
587 588 * @dst: remapped result
  589 + * @src: subset to be remapped
588 590 * @old: defines domain of map
589 591 * @new: defines range of map
590 592 * @bits: number of bits in each of these bitmaps
591 593  
592 594  
593 595  
594 596  
595 597  
596 598  
597 599  
... ... @@ -596,49 +598,42 @@
596 598 * weight of @old, map the position of the n-th set bit in @old to
597 599 * the position of the m-th set bit in @new, where m == n % w.
598 600 *
599   - * If either of the @old and @new bitmaps are empty, or if@src and @dst
600   - * point to the same location, then this routine does nothing.
  601 + * If either of the @old and @new bitmaps are empty, or if @src and
  602 + * @dst point to the same location, then this routine copies @src
  603 + * to @dst.
601 604 *
602   - * The positions of unset bits in @old are mapped to the position of
603   - * the first set bit in @new.
  605 + * The positions of unset bits in @old are mapped to themselves
  606 + * (the identify map).
604 607 *
605 608 * Apply the above specified mapping to @src, placing the result in
606 609 * @dst, clearing any bits previously set in @dst.
607 610 *
608   - * The resulting value of @dst will have either the same weight as
609   - * @src, or less weight in the general case that the mapping wasn't
610   - * injective due to the weight of @new being less than that of @old.
611   - * The resulting value of @dst will never have greater weight than
612   - * that of @src, except perhaps in the case that one of the above
613   - * conditions was not met and this routine just returned.
614   - *
615 611 * For example, lets say that @old has bits 4 through 7 set, and
616 612 * @new has bits 12 through 15 set. This defines the mapping of bit
617 613 * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
618   - * bit positions to 12 (the first set bit in @new. So if say @src
619   - * comes into this routine with bits 1, 5 and 7 set, then @dst should
620   - * leave with bits 12, 13 and 15 set.
  614 + * bit positions unchanged. So if say @src comes into this routine
  615 + * with bits 1, 5 and 7 set, then @dst should leave with bits 1,
  616 + * 13 and 15 set.
621 617 */
622 618 void bitmap_remap(unsigned long *dst, const unsigned long *src,
623 619 const unsigned long *old, const unsigned long *new,
624 620 int bits)
625 621 {
626   - int s;
  622 + int oldbit, w;
627 623  
628   - if (bitmap_weight(old, bits) == 0)
629   - return;
630   - if (bitmap_weight(new, bits) == 0)
631   - return;
632 624 if (dst == src) /* following doesn't handle inplace remaps */
633 625 return;
634   -
635 626 bitmap_zero(dst, bits);
636   - for (s = find_first_bit(src, bits);
637   - s < bits;
638   - s = find_next_bit(src, bits, s + 1)) {
639   - int x = bitmap_pos_to_ord(old, s, bits);
640   - int y = bitmap_ord_to_pos(new, x, bits);
641   - set_bit(y, dst);
  627 +
  628 + w = bitmap_weight(new, bits);
  629 + for (oldbit = find_first_bit(src, bits);
  630 + oldbit < bits;
  631 + oldbit = find_next_bit(src, bits, oldbit + 1)) {
  632 + int n = bitmap_pos_to_ord(old, oldbit, bits);
  633 + if (n < 0 || w == 0)
  634 + set_bit(oldbit, dst); /* identity map */
  635 + else
  636 + set_bit(bitmap_ord_to_pos(new, n % w, bits), dst);
642 637 }
643 638 }
644 639 EXPORT_SYMBOL(bitmap_remap);
... ... @@ -657,8 +652,8 @@
657 652 * weight of @old, map the position of the n-th set bit in @old to
658 653 * the position of the m-th set bit in @new, where m == n % w.
659 654 *
660   - * The positions of unset bits in @old are mapped to the position of
661   - * the first set bit in @new.
  655 + * The positions of unset bits in @old are mapped to themselves
  656 + * (the identify map).
662 657 *
663 658 * Apply the above specified mapping to bit position @oldbit, returning
664 659 * the new bit position.
665 660  
... ... @@ -666,14 +661,18 @@
666 661 * For example, lets say that @old has bits 4 through 7 set, and
667 662 * @new has bits 12 through 15 set. This defines the mapping of bit
668 663 * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
669   - * bit positions to 12 (the first set bit in @new. So if say @oldbit
670   - * is 5, then this routine returns 13.
  664 + * bit positions unchanged. So if say @oldbit is 5, then this routine
  665 + * returns 13.
671 666 */
672 667 int bitmap_bitremap(int oldbit, const unsigned long *old,
673 668 const unsigned long *new, int bits)
674 669 {
675   - int x = bitmap_pos_to_ord(old, oldbit, bits);
676   - return bitmap_ord_to_pos(new, x, bits);
  670 + int w = bitmap_weight(new, bits);
  671 + int n = bitmap_pos_to_ord(old, oldbit, bits);
  672 + if (n < 0 || w == 0)
  673 + return oldbit;
  674 + else
  675 + return bitmap_ord_to_pos(new, n % w, bits);
677 676 }
678 677 EXPORT_SYMBOL(bitmap_bitremap);
679 678