Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'cpus4096' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'cpus4096' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
cpumask: introduce new API, without changing anything, v3
cpumask: new API, v2
cpumask: introduce new API, without changing anything

+701 -2
+557 -2
include/linux/cpumask.h
··· 5 5 * Cpumasks provide a bitmap suitable for representing the 6 6 * set of CPU's in a system, one bit position per CPU number. 7 7 * 8 + * The new cpumask_ ops take a "struct cpumask *"; the old ones 9 + * use cpumask_t. 10 + * 8 11 * See detailed comments in the file linux/bitmap.h describing the 9 12 * data type on which these cpumasks are based. 10 13 * ··· 34 31 * will span the entire range of NR_CPUS. 35 32 * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 33 * 37 - * The available cpumask operations are: 34 + * The obsolescent cpumask operations are: 38 35 * 39 36 * void cpu_set(cpu, mask) turn on bit 'cpu' in mask 40 37 * void cpu_clear(cpu, mask) turn off bit 'cpu' in mask ··· 141 138 #include <linux/threads.h> 142 139 #include <linux/bitmap.h> 143 140 144 - typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; 141 + typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; 145 142 extern cpumask_t _unused_cpumask_arg_; 146 143 147 144 #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst)) ··· 530 527 #define for_each_online_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_online_map) 531 528 #define for_each_present_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_present_map) 532 529 530 + /* These are the new versions of the cpumask operators: passed by pointer. 531 + * The older versions will be implemented in terms of these, then deleted. */ 532 + #define cpumask_bits(maskp) ((maskp)->bits) 533 + 534 + #if NR_CPUS <= BITS_PER_LONG 535 + #define CPU_BITS_ALL \ 536 + { \ 537 + [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ 538 + } 539 + 540 + /* This produces more efficient code. */ 541 + #define nr_cpumask_bits NR_CPUS 542 + 543 + #else /* NR_CPUS > BITS_PER_LONG */ 544 + 545 + #define CPU_BITS_ALL \ 546 + { \ 547 + [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL, \ 548 + [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ 549 + } 550 + 551 + #define nr_cpumask_bits nr_cpu_ids 552 + #endif /* NR_CPUS > BITS_PER_LONG */ 553 + 554 + /* verify cpu argument to cpumask_* operators */ 555 + static inline unsigned int cpumask_check(unsigned int cpu) 556 + { 557 + #ifdef CONFIG_DEBUG_PER_CPU_MAPS 558 + WARN_ON_ONCE(cpu >= nr_cpumask_bits); 559 + #endif /* CONFIG_DEBUG_PER_CPU_MAPS */ 560 + return cpu; 561 + } 562 + 563 + #if NR_CPUS == 1 564 + /* Uniprocessor. Assume all masks are "1". */ 565 + static inline unsigned int cpumask_first(const struct cpumask *srcp) 566 + { 567 + return 0; 568 + } 569 + 570 + /* Valid inputs for n are -1 and 0. */ 571 + static inline unsigned int cpumask_next(int n, const struct cpumask *srcp) 572 + { 573 + return n+1; 574 + } 575 + 576 + static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp) 577 + { 578 + return n+1; 579 + } 580 + 581 + static inline unsigned int cpumask_next_and(int n, 582 + const struct cpumask *srcp, 583 + const struct cpumask *andp) 584 + { 585 + return n+1; 586 + } 587 + 588 + /* cpu must be a valid cpu, ie 0, so there's no other choice. */ 589 + static inline unsigned int cpumask_any_but(const struct cpumask *mask, 590 + unsigned int cpu) 591 + { 592 + return 1; 593 + } 594 + 595 + #define for_each_cpu(cpu, mask) \ 596 + for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) 597 + #define for_each_cpu_and(cpu, mask, and) \ 598 + for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)and) 599 + #else 600 + /** 601 + * cpumask_first - get the first cpu in a cpumask 602 + * @srcp: the cpumask pointer 603 + * 604 + * Returns >= nr_cpu_ids if no cpus set. 605 + */ 606 + static inline unsigned int cpumask_first(const struct cpumask *srcp) 607 + { 608 + return find_first_bit(cpumask_bits(srcp), nr_cpumask_bits); 609 + } 610 + 611 + /** 612 + * cpumask_next - get the next cpu in a cpumask 613 + * @n: the cpu prior to the place to search (ie. return will be > @n) 614 + * @srcp: the cpumask pointer 615 + * 616 + * Returns >= nr_cpu_ids if no further cpus set. 617 + */ 618 + static inline unsigned int cpumask_next(int n, const struct cpumask *srcp) 619 + { 620 + /* -1 is a legal arg here. */ 621 + if (n != -1) 622 + cpumask_check(n); 623 + return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1); 624 + } 625 + 626 + /** 627 + * cpumask_next_zero - get the next unset cpu in a cpumask 628 + * @n: the cpu prior to the place to search (ie. return will be > @n) 629 + * @srcp: the cpumask pointer 630 + * 631 + * Returns >= nr_cpu_ids if no further cpus unset. 632 + */ 633 + static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp) 634 + { 635 + /* -1 is a legal arg here. */ 636 + if (n != -1) 637 + cpumask_check(n); 638 + return find_next_zero_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1); 639 + } 640 + 641 + int cpumask_next_and(int n, const struct cpumask *, const struct cpumask *); 642 + int cpumask_any_but(const struct cpumask *mask, unsigned int cpu); 643 + 644 + /** 645 + * for_each_cpu - iterate over every cpu in a mask 646 + * @cpu: the (optionally unsigned) integer iterator 647 + * @mask: the cpumask pointer 648 + * 649 + * After the loop, cpu is >= nr_cpu_ids. 650 + */ 651 + #define for_each_cpu(cpu, mask) \ 652 + for ((cpu) = -1; \ 653 + (cpu) = cpumask_next((cpu), (mask)), \ 654 + (cpu) < nr_cpu_ids;) 655 + 656 + /** 657 + * for_each_cpu_and - iterate over every cpu in both masks 658 + * @cpu: the (optionally unsigned) integer iterator 659 + * @mask: the first cpumask pointer 660 + * @and: the second cpumask pointer 661 + * 662 + * This saves a temporary CPU mask in many places. It is equivalent to: 663 + * struct cpumask tmp; 664 + * cpumask_and(&tmp, &mask, &and); 665 + * for_each_cpu(cpu, &tmp) 666 + * ... 667 + * 668 + * After the loop, cpu is >= nr_cpu_ids. 669 + */ 670 + #define for_each_cpu_and(cpu, mask, and) \ 671 + for ((cpu) = -1; \ 672 + (cpu) = cpumask_next_and((cpu), (mask), (and)), \ 673 + (cpu) < nr_cpu_ids;) 674 + #endif /* SMP */ 675 + 676 + #define CPU_BITS_NONE \ 677 + { \ 678 + [0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL \ 679 + } 680 + 681 + #define CPU_BITS_CPU0 \ 682 + { \ 683 + [0] = 1UL \ 684 + } 685 + 686 + /** 687 + * cpumask_set_cpu - set a cpu in a cpumask 688 + * @cpu: cpu number (< nr_cpu_ids) 689 + * @dstp: the cpumask pointer 690 + */ 691 + static inline void cpumask_set_cpu(unsigned int cpu, struct cpumask *dstp) 692 + { 693 + set_bit(cpumask_check(cpu), cpumask_bits(dstp)); 694 + } 695 + 696 + /** 697 + * cpumask_clear_cpu - clear a cpu in a cpumask 698 + * @cpu: cpu number (< nr_cpu_ids) 699 + * @dstp: the cpumask pointer 700 + */ 701 + static inline void cpumask_clear_cpu(int cpu, struct cpumask *dstp) 702 + { 703 + clear_bit(cpumask_check(cpu), cpumask_bits(dstp)); 704 + } 705 + 706 + /** 707 + * cpumask_test_cpu - test for a cpu in a cpumask 708 + * @cpu: cpu number (< nr_cpu_ids) 709 + * @cpumask: the cpumask pointer 710 + * 711 + * No static inline type checking - see Subtlety (1) above. 712 + */ 713 + #define cpumask_test_cpu(cpu, cpumask) \ 714 + test_bit(cpumask_check(cpu), (cpumask)->bits) 715 + 716 + /** 717 + * cpumask_test_and_set_cpu - atomically test and set a cpu in a cpumask 718 + * @cpu: cpu number (< nr_cpu_ids) 719 + * @cpumask: the cpumask pointer 720 + * 721 + * test_and_set_bit wrapper for cpumasks. 722 + */ 723 + static inline int cpumask_test_and_set_cpu(int cpu, struct cpumask *cpumask) 724 + { 725 + return test_and_set_bit(cpumask_check(cpu), cpumask_bits(cpumask)); 726 + } 727 + 728 + /** 729 + * cpumask_setall - set all cpus (< nr_cpu_ids) in a cpumask 730 + * @dstp: the cpumask pointer 731 + */ 732 + static inline void cpumask_setall(struct cpumask *dstp) 733 + { 734 + bitmap_fill(cpumask_bits(dstp), nr_cpumask_bits); 735 + } 736 + 737 + /** 738 + * cpumask_clear - clear all cpus (< nr_cpu_ids) in a cpumask 739 + * @dstp: the cpumask pointer 740 + */ 741 + static inline void cpumask_clear(struct cpumask *dstp) 742 + { 743 + bitmap_zero(cpumask_bits(dstp), nr_cpumask_bits); 744 + } 745 + 746 + /** 747 + * cpumask_and - *dstp = *src1p & *src2p 748 + * @dstp: the cpumask result 749 + * @src1p: the first input 750 + * @src2p: the second input 751 + */ 752 + static inline void cpumask_and(struct cpumask *dstp, 753 + const struct cpumask *src1p, 754 + const struct cpumask *src2p) 755 + { 756 + bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p), 757 + cpumask_bits(src2p), nr_cpumask_bits); 758 + } 759 + 760 + /** 761 + * cpumask_or - *dstp = *src1p | *src2p 762 + * @dstp: the cpumask result 763 + * @src1p: the first input 764 + * @src2p: the second input 765 + */ 766 + static inline void cpumask_or(struct cpumask *dstp, const struct cpumask *src1p, 767 + const struct cpumask *src2p) 768 + { 769 + bitmap_or(cpumask_bits(dstp), cpumask_bits(src1p), 770 + cpumask_bits(src2p), nr_cpumask_bits); 771 + } 772 + 773 + /** 774 + * cpumask_xor - *dstp = *src1p ^ *src2p 775 + * @dstp: the cpumask result 776 + * @src1p: the first input 777 + * @src2p: the second input 778 + */ 779 + static inline void cpumask_xor(struct cpumask *dstp, 780 + const struct cpumask *src1p, 781 + const struct cpumask *src2p) 782 + { 783 + bitmap_xor(cpumask_bits(dstp), cpumask_bits(src1p), 784 + cpumask_bits(src2p), nr_cpumask_bits); 785 + } 786 + 787 + /** 788 + * cpumask_andnot - *dstp = *src1p & ~*src2p 789 + * @dstp: the cpumask result 790 + * @src1p: the first input 791 + * @src2p: the second input 792 + */ 793 + static inline void cpumask_andnot(struct cpumask *dstp, 794 + const struct cpumask *src1p, 795 + const struct cpumask *src2p) 796 + { 797 + bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p), 798 + cpumask_bits(src2p), nr_cpumask_bits); 799 + } 800 + 801 + /** 802 + * cpumask_complement - *dstp = ~*srcp 803 + * @dstp: the cpumask result 804 + * @srcp: the input to invert 805 + */ 806 + static inline void cpumask_complement(struct cpumask *dstp, 807 + const struct cpumask *srcp) 808 + { 809 + bitmap_complement(cpumask_bits(dstp), cpumask_bits(srcp), 810 + nr_cpumask_bits); 811 + } 812 + 813 + /** 814 + * cpumask_equal - *src1p == *src2p 815 + * @src1p: the first input 816 + * @src2p: the second input 817 + */ 818 + static inline bool cpumask_equal(const struct cpumask *src1p, 819 + const struct cpumask *src2p) 820 + { 821 + return bitmap_equal(cpumask_bits(src1p), cpumask_bits(src2p), 822 + nr_cpumask_bits); 823 + } 824 + 825 + /** 826 + * cpumask_intersects - (*src1p & *src2p) != 0 827 + * @src1p: the first input 828 + * @src2p: the second input 829 + */ 830 + static inline bool cpumask_intersects(const struct cpumask *src1p, 831 + const struct cpumask *src2p) 832 + { 833 + return bitmap_intersects(cpumask_bits(src1p), cpumask_bits(src2p), 834 + nr_cpumask_bits); 835 + } 836 + 837 + /** 838 + * cpumask_subset - (*src1p & ~*src2p) == 0 839 + * @src1p: the first input 840 + * @src2p: the second input 841 + */ 842 + static inline int cpumask_subset(const struct cpumask *src1p, 843 + const struct cpumask *src2p) 844 + { 845 + return bitmap_subset(cpumask_bits(src1p), cpumask_bits(src2p), 846 + nr_cpumask_bits); 847 + } 848 + 849 + /** 850 + * cpumask_empty - *srcp == 0 851 + * @srcp: the cpumask to that all cpus < nr_cpu_ids are clear. 852 + */ 853 + static inline bool cpumask_empty(const struct cpumask *srcp) 854 + { 855 + return bitmap_empty(cpumask_bits(srcp), nr_cpumask_bits); 856 + } 857 + 858 + /** 859 + * cpumask_full - *srcp == 0xFFFFFFFF... 860 + * @srcp: the cpumask to that all cpus < nr_cpu_ids are set. 861 + */ 862 + static inline bool cpumask_full(const struct cpumask *srcp) 863 + { 864 + return bitmap_full(cpumask_bits(srcp), nr_cpumask_bits); 865 + } 866 + 867 + /** 868 + * cpumask_weight - Count of bits in *srcp 869 + * @srcp: the cpumask to count bits (< nr_cpu_ids) in. 870 + */ 871 + static inline unsigned int cpumask_weight(const struct cpumask *srcp) 872 + { 873 + return bitmap_weight(cpumask_bits(srcp), nr_cpumask_bits); 874 + } 875 + 876 + /** 877 + * cpumask_shift_right - *dstp = *srcp >> n 878 + * @dstp: the cpumask result 879 + * @srcp: the input to shift 880 + * @n: the number of bits to shift by 881 + */ 882 + static inline void cpumask_shift_right(struct cpumask *dstp, 883 + const struct cpumask *srcp, int n) 884 + { 885 + bitmap_shift_right(cpumask_bits(dstp), cpumask_bits(srcp), n, 886 + nr_cpumask_bits); 887 + } 888 + 889 + /** 890 + * cpumask_shift_left - *dstp = *srcp << n 891 + * @dstp: the cpumask result 892 + * @srcp: the input to shift 893 + * @n: the number of bits to shift by 894 + */ 895 + static inline void cpumask_shift_left(struct cpumask *dstp, 896 + const struct cpumask *srcp, int n) 897 + { 898 + bitmap_shift_left(cpumask_bits(dstp), cpumask_bits(srcp), n, 899 + nr_cpumask_bits); 900 + } 901 + 902 + /** 903 + * cpumask_copy - *dstp = *srcp 904 + * @dstp: the result 905 + * @srcp: the input cpumask 906 + */ 907 + static inline void cpumask_copy(struct cpumask *dstp, 908 + const struct cpumask *srcp) 909 + { 910 + bitmap_copy(cpumask_bits(dstp), cpumask_bits(srcp), nr_cpumask_bits); 911 + } 912 + 913 + /** 914 + * cpumask_any - pick a "random" cpu from *srcp 915 + * @srcp: the input cpumask 916 + * 917 + * Returns >= nr_cpu_ids if no cpus set. 918 + */ 919 + #define cpumask_any(srcp) cpumask_first(srcp) 920 + 921 + /** 922 + * cpumask_first_and - return the first cpu from *srcp1 & *srcp2 923 + * @src1p: the first input 924 + * @src2p: the second input 925 + * 926 + * Returns >= nr_cpu_ids if no cpus set in both. See also cpumask_next_and(). 927 + */ 928 + #define cpumask_first_and(src1p, src2p) cpumask_next_and(-1, (src1p), (src2p)) 929 + 930 + /** 931 + * cpumask_any_and - pick a "random" cpu from *mask1 & *mask2 932 + * @mask1: the first input cpumask 933 + * @mask2: the second input cpumask 934 + * 935 + * Returns >= nr_cpu_ids if no cpus set. 936 + */ 937 + #define cpumask_any_and(mask1, mask2) cpumask_first_and((mask1), (mask2)) 938 + 939 + /** 940 + * cpumask_of - the cpumask containing just a given cpu 941 + * @cpu: the cpu (<= nr_cpu_ids) 942 + */ 943 + #define cpumask_of(cpu) (get_cpu_mask(cpu)) 944 + 945 + /** 946 + * to_cpumask - convert an NR_CPUS bitmap to a struct cpumask * 947 + * @bitmap: the bitmap 948 + * 949 + * There are a few places where cpumask_var_t isn't appropriate and 950 + * static cpumasks must be used (eg. very early boot), yet we don't 951 + * expose the definition of 'struct cpumask'. 952 + * 953 + * This does the conversion, and can be used as a constant initializer. 954 + */ 955 + #define to_cpumask(bitmap) \ 956 + ((struct cpumask *)(1 ? (bitmap) \ 957 + : (void *)sizeof(__check_is_bitmap(bitmap)))) 958 + 959 + static inline int __check_is_bitmap(const unsigned long *bitmap) 960 + { 961 + return 1; 962 + } 963 + 964 + /** 965 + * cpumask_size - size to allocate for a 'struct cpumask' in bytes 966 + * 967 + * This will eventually be a runtime variable, depending on nr_cpu_ids. 968 + */ 969 + static inline size_t cpumask_size(void) 970 + { 971 + /* FIXME: Once all cpumask assignments are eliminated, this 972 + * can be nr_cpumask_bits */ 973 + return BITS_TO_LONGS(NR_CPUS) * sizeof(long); 974 + } 975 + 976 + /* 977 + * cpumask_var_t: struct cpumask for stack usage. 978 + * 979 + * Oh, the wicked games we play! In order to make kernel coding a 980 + * little more difficult, we typedef cpumask_var_t to an array or a 981 + * pointer: doing &mask on an array is a noop, so it still works. 982 + * 983 + * ie. 984 + * cpumask_var_t tmpmask; 985 + * if (!alloc_cpumask_var(&tmpmask, GFP_KERNEL)) 986 + * return -ENOMEM; 987 + * 988 + * ... use 'tmpmask' like a normal struct cpumask * ... 989 + * 990 + * free_cpumask_var(tmpmask); 991 + */ 992 + #ifdef CONFIG_CPUMASK_OFFSTACK 993 + typedef struct cpumask *cpumask_var_t; 994 + 995 + bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags); 996 + void alloc_bootmem_cpumask_var(cpumask_var_t *mask); 997 + void free_cpumask_var(cpumask_var_t mask); 998 + void free_bootmem_cpumask_var(cpumask_var_t mask); 999 + 1000 + #else 1001 + typedef struct cpumask cpumask_var_t[1]; 1002 + 1003 + static inline bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) 1004 + { 1005 + return true; 1006 + } 1007 + 1008 + static inline void alloc_bootmem_cpumask_var(cpumask_var_t *mask) 1009 + { 1010 + } 1011 + 1012 + static inline void free_cpumask_var(cpumask_var_t mask) 1013 + { 1014 + } 1015 + 1016 + static inline void free_bootmem_cpumask_var(cpumask_var_t mask) 1017 + { 1018 + } 1019 + #endif /* CONFIG_CPUMASK_OFFSTACK */ 1020 + 1021 + /* The pointer versions of the maps, these will become the primary versions. */ 1022 + #define cpu_possible_mask ((const struct cpumask *)&cpu_possible_map) 1023 + #define cpu_online_mask ((const struct cpumask *)&cpu_online_map) 1024 + #define cpu_present_mask ((const struct cpumask *)&cpu_present_map) 1025 + #define cpu_active_mask ((const struct cpumask *)&cpu_active_map) 1026 + 1027 + /* It's common to want to use cpu_all_mask in struct member initializers, 1028 + * so it has to refer to an address rather than a pointer. */ 1029 + extern const DECLARE_BITMAP(cpu_all_bits, NR_CPUS); 1030 + #define cpu_all_mask to_cpumask(cpu_all_bits) 1031 + 1032 + /* First bits of cpu_bit_bitmap are in fact unset. */ 1033 + #define cpu_none_mask to_cpumask(cpu_bit_bitmap[0]) 1034 + 1035 + /* Wrappers for arch boot code to manipulate normally-constant masks */ 1036 + static inline void set_cpu_possible(unsigned int cpu, bool possible) 1037 + { 1038 + if (possible) 1039 + cpumask_set_cpu(cpu, &cpu_possible_map); 1040 + else 1041 + cpumask_clear_cpu(cpu, &cpu_possible_map); 1042 + } 1043 + 1044 + static inline void set_cpu_present(unsigned int cpu, bool present) 1045 + { 1046 + if (present) 1047 + cpumask_set_cpu(cpu, &cpu_present_map); 1048 + else 1049 + cpumask_clear_cpu(cpu, &cpu_present_map); 1050 + } 1051 + 1052 + static inline void set_cpu_online(unsigned int cpu, bool online) 1053 + { 1054 + if (online) 1055 + cpumask_set_cpu(cpu, &cpu_online_map); 1056 + else 1057 + cpumask_clear_cpu(cpu, &cpu_online_map); 1058 + } 1059 + 1060 + static inline void set_cpu_active(unsigned int cpu, bool active) 1061 + { 1062 + if (active) 1063 + cpumask_set_cpu(cpu, &cpu_active_map); 1064 + else 1065 + cpumask_clear_cpu(cpu, &cpu_active_map); 1066 + } 1067 + 1068 + static inline void init_cpu_present(const struct cpumask *src) 1069 + { 1070 + cpumask_copy(&cpu_present_map, src); 1071 + } 1072 + 1073 + static inline void init_cpu_possible(const struct cpumask *src) 1074 + { 1075 + cpumask_copy(&cpu_possible_map, src); 1076 + } 1077 + 1078 + static inline void init_cpu_online(const struct cpumask *src) 1079 + { 1080 + cpumask_copy(&cpu_online_map, src); 1081 + } 533 1082 #endif /* __LINUX_CPUMASK_H */
+9
include/linux/smp.h
··· 64 64 * Call a function on all other processors 65 65 */ 66 66 int smp_call_function(void(*func)(void *info), void *info, int wait); 67 + /* Deprecated: use smp_call_function_many() which uses a cpumask ptr. */ 67 68 int smp_call_function_mask(cpumask_t mask, void(*func)(void *info), void *info, 68 69 int wait); 70 + 71 + static inline void smp_call_function_many(const struct cpumask *mask, 72 + void (*func)(void *info), void *info, 73 + int wait) 74 + { 75 + smp_call_function_mask(*mask, func, info, wait); 76 + } 77 + 69 78 int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, 70 79 int wait); 71 80 void __smp_call_function_single(int cpuid, struct call_single_data *data);
+8
include/linux/workqueue.h
··· 240 240 cancel_delayed_work_sync(work); 241 241 } 242 242 243 + #ifndef CONFIG_SMP 244 + static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) 245 + { 246 + return fn(arg); 247 + } 248 + #else 249 + long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg); 250 + #endif /* CONFIG_SMP */ 243 251 #endif
+3
kernel/cpu.c
··· 499 499 #endif 500 500 }; 501 501 EXPORT_SYMBOL_GPL(cpu_bit_bitmap); 502 + 503 + const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL; 504 + EXPORT_SYMBOL(cpu_all_bits);
+45
kernel/workqueue.c
··· 970 970 return ret; 971 971 } 972 972 973 + #ifdef CONFIG_SMP 974 + struct work_for_cpu { 975 + struct work_struct work; 976 + long (*fn)(void *); 977 + void *arg; 978 + long ret; 979 + }; 980 + 981 + static void do_work_for_cpu(struct work_struct *w) 982 + { 983 + struct work_for_cpu *wfc = container_of(w, struct work_for_cpu, work); 984 + 985 + wfc->ret = wfc->fn(wfc->arg); 986 + } 987 + 988 + /** 989 + * work_on_cpu - run a function in user context on a particular cpu 990 + * @cpu: the cpu to run on 991 + * @fn: the function to run 992 + * @arg: the function arg 993 + * 994 + * This will return -EINVAL in the cpu is not online, or the return value 995 + * of @fn otherwise. 996 + */ 997 + long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) 998 + { 999 + struct work_for_cpu wfc; 1000 + 1001 + INIT_WORK(&wfc.work, do_work_for_cpu); 1002 + wfc.fn = fn; 1003 + wfc.arg = arg; 1004 + get_online_cpus(); 1005 + if (unlikely(!cpu_online(cpu))) 1006 + wfc.ret = -EINVAL; 1007 + else { 1008 + schedule_work_on(cpu, &wfc.work); 1009 + flush_work(&wfc.work); 1010 + } 1011 + put_online_cpus(); 1012 + 1013 + return wfc.ret; 1014 + } 1015 + EXPORT_SYMBOL_GPL(work_on_cpu); 1016 + #endif /* CONFIG_SMP */ 1017 + 973 1018 void __init init_workqueues(void) 974 1019 { 975 1020 cpu_populated_map = cpu_online_map;
+79
lib/cpumask.c
··· 2 2 #include <linux/bitops.h> 3 3 #include <linux/cpumask.h> 4 4 #include <linux/module.h> 5 + #include <linux/bootmem.h> 5 6 6 7 int __first_cpu(const cpumask_t *srcp) 7 8 { ··· 36 35 return cpu; 37 36 } 38 37 EXPORT_SYMBOL(__any_online_cpu); 38 + 39 + /** 40 + * cpumask_next_and - get the next cpu in *src1p & *src2p 41 + * @n: the cpu prior to the place to search (ie. return will be > @n) 42 + * @src1p: the first cpumask pointer 43 + * @src2p: the second cpumask pointer 44 + * 45 + * Returns >= nr_cpu_ids if no further cpus set in both. 46 + */ 47 + int cpumask_next_and(int n, const struct cpumask *src1p, 48 + const struct cpumask *src2p) 49 + { 50 + while ((n = cpumask_next(n, src1p)) < nr_cpu_ids) 51 + if (cpumask_test_cpu(n, src2p)) 52 + break; 53 + return n; 54 + } 55 + EXPORT_SYMBOL(cpumask_next_and); 56 + 57 + /** 58 + * cpumask_any_but - return a "random" in a cpumask, but not this one. 59 + * @mask: the cpumask to search 60 + * @cpu: the cpu to ignore. 61 + * 62 + * Often used to find any cpu but smp_processor_id() in a mask. 63 + * Returns >= nr_cpu_ids if no cpus set. 64 + */ 65 + int cpumask_any_but(const struct cpumask *mask, unsigned int cpu) 66 + { 67 + unsigned int i; 68 + 69 + cpumask_check(cpu); 70 + for_each_cpu(i, mask) 71 + if (i != cpu) 72 + break; 73 + return i; 74 + } 75 + 76 + /* These are not inline because of header tangles. */ 77 + #ifdef CONFIG_CPUMASK_OFFSTACK 78 + bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) 79 + { 80 + if (likely(slab_is_available())) 81 + *mask = kmalloc(cpumask_size(), flags); 82 + else { 83 + #ifdef CONFIG_DEBUG_PER_CPU_MAPS 84 + printk(KERN_ERR 85 + "=> alloc_cpumask_var: kmalloc not available!\n"); 86 + dump_stack(); 87 + #endif 88 + *mask = NULL; 89 + } 90 + #ifdef CONFIG_DEBUG_PER_CPU_MAPS 91 + if (!*mask) { 92 + printk(KERN_ERR "=> alloc_cpumask_var: failed!\n"); 93 + dump_stack(); 94 + } 95 + #endif 96 + return *mask != NULL; 97 + } 98 + EXPORT_SYMBOL(alloc_cpumask_var); 99 + 100 + void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask) 101 + { 102 + *mask = alloc_bootmem(cpumask_size()); 103 + } 104 + 105 + void free_cpumask_var(cpumask_var_t mask) 106 + { 107 + kfree(mask); 108 + } 109 + EXPORT_SYMBOL(free_cpumask_var); 110 + 111 + void __init free_bootmem_cpumask_var(cpumask_var_t mask) 112 + { 113 + free_bootmem((unsigned long)mask, cpumask_size()); 114 + } 115 + #endif