diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2008-04-19 13:45:00 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-04-19 13:45:00 -0400 |
| commit | f00b45c145981b43c7e7f66315ac77534c938cbf (patch) | |
| tree | 56604b844199ded71c518706f3c3a11275432266 /kernel | |
| parent | 06379aba522ebdabca37446ea988a23c43c03c67 (diff) | |
sched: /debug/sched_features
provide a text based interface to the scheduler features; this saves the
'user' from setting bits using decimal arithmetic.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched.c | 162 | ||||
| -rw-r--r-- | kernel/sched_features.h | 10 |
2 files changed, 150 insertions, 22 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 8f03817e7dd3..b59a44e1ea44 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -68,6 +68,8 @@ | |||
| 68 | #include <linux/hrtimer.h> | 68 | #include <linux/hrtimer.h> |
| 69 | #include <linux/tick.h> | 69 | #include <linux/tick.h> |
| 70 | #include <linux/bootmem.h> | 70 | #include <linux/bootmem.h> |
| 71 | #include <linux/debugfs.h> | ||
| 72 | #include <linux/ctype.h> | ||
| 71 | 73 | ||
| 72 | #include <asm/tlb.h> | 74 | #include <asm/tlb.h> |
| 73 | #include <asm/irq_regs.h> | 75 | #include <asm/irq_regs.h> |
| @@ -732,32 +734,148 @@ static void update_rq_clock(struct rq *rq) | |||
| 732 | /* | 734 | /* |
| 733 | * Debugging: various feature bits | 735 | * Debugging: various feature bits |
| 734 | */ | 736 | */ |
| 737 | |||
| 738 | #define SCHED_FEAT(name, enabled) \ | ||
| 739 | __SCHED_FEAT_##name , | ||
| 740 | |||
| 735 | enum { | 741 | enum { |
| 736 | SCHED_FEAT_NEW_FAIR_SLEEPERS = 1, | 742 | #include "sched_features.h" |
| 737 | SCHED_FEAT_WAKEUP_PREEMPT = 2, | ||
| 738 | SCHED_FEAT_START_DEBIT = 4, | ||
| 739 | SCHED_FEAT_AFFINE_WAKEUPS = 8, | ||
| 740 | SCHED_FEAT_CACHE_HOT_BUDDY = 16, | ||
| 741 | SCHED_FEAT_SYNC_WAKEUPS = 32, | ||
| 742 | SCHED_FEAT_HRTICK = 64, | ||
| 743 | SCHED_FEAT_DOUBLE_TICK = 128, | ||
| 744 | SCHED_FEAT_NORMALIZED_SLEEPER = 256, | ||
| 745 | SCHED_FEAT_DEADLINE = 512, | ||
| 746 | }; | 743 | }; |
| 747 | 744 | ||
| 745 | #undef SCHED_FEAT | ||
| 746 | |||
| 747 | #define SCHED_FEAT(name, enabled) \ | ||
| 748 | (1UL << __SCHED_FEAT_##name) * enabled | | ||
| 749 | |||
| 748 | const_debug unsigned int sysctl_sched_features = | 750 | const_debug unsigned int sysctl_sched_features = |
| 749 | SCHED_FEAT_NEW_FAIR_SLEEPERS * 1 | | 751 | #include "sched_features.h" |
| 750 | SCHED_FEAT_WAKEUP_PREEMPT * 1 | | 752 | 0; |
| 751 | SCHED_FEAT_START_DEBIT * 1 | | 753 | |
| 752 | SCHED_FEAT_AFFINE_WAKEUPS * 1 | | 754 | #undef SCHED_FEAT |
| 753 | SCHED_FEAT_CACHE_HOT_BUDDY * 1 | | 755 | |
| 754 | SCHED_FEAT_SYNC_WAKEUPS * 1 | | 756 | #ifdef CONFIG_SCHED_DEBUG |
| 755 | SCHED_FEAT_HRTICK * 1 | | 757 | #define SCHED_FEAT(name, enabled) \ |
| 756 | SCHED_FEAT_DOUBLE_TICK * 0 | | 758 | #name , |
| 757 | SCHED_FEAT_NORMALIZED_SLEEPER * 1 | | 759 | |
| 758 | SCHED_FEAT_DEADLINE * 1; | 760 | __read_mostly char *sched_feat_names[] = { |
| 759 | 761 | #include "sched_features.h" | |
| 760 | #define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x) | 762 | NULL |
| 763 | }; | ||
| 764 | |||
| 765 | #undef SCHED_FEAT | ||
| 766 | |||
| 767 | int sched_feat_open(struct inode *inode, struct file *filp) | ||
| 768 | { | ||
| 769 | filp->private_data = inode->i_private; | ||
| 770 | return 0; | ||
| 771 | } | ||
| 772 | |||
| 773 | static ssize_t | ||
| 774 | sched_feat_read(struct file *filp, char __user *ubuf, | ||
| 775 | size_t cnt, loff_t *ppos) | ||
| 776 | { | ||
| 777 | char *buf; | ||
| 778 | int r = 0; | ||
| 779 | int len = 0; | ||
| 780 | int i; | ||
| 781 | |||
| 782 | for (i = 0; sched_feat_names[i]; i++) { | ||
| 783 | len += strlen(sched_feat_names[i]); | ||
| 784 | len += 4; | ||
| 785 | } | ||
| 786 | |||
| 787 | buf = kmalloc(len + 2, GFP_KERNEL); | ||
| 788 | if (!buf) | ||
| 789 | return -ENOMEM; | ||
| 790 | |||
| 791 | for (i = 0; sched_feat_names[i]; i++) { | ||
| 792 | if (sysctl_sched_features & (1UL << i)) | ||
| 793 | r += sprintf(buf + r, "%s ", sched_feat_names[i]); | ||
| 794 | else | ||
| 795 | r += sprintf(buf + r, "no_%s ", sched_feat_names[i]); | ||
| 796 | } | ||
| 797 | |||
| 798 | r += sprintf(buf + r, "\n"); | ||
| 799 | WARN_ON(r >= len + 2); | ||
| 800 | |||
| 801 | r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | ||
| 802 | |||
| 803 | kfree(buf); | ||
| 804 | |||
| 805 | return r; | ||
| 806 | } | ||
| 807 | |||
| 808 | static ssize_t | ||
| 809 | sched_feat_write(struct file *filp, const char __user *ubuf, | ||
| 810 | size_t cnt, loff_t *ppos) | ||
| 811 | { | ||
| 812 | char buf[64]; | ||
| 813 | char *cmp = buf; | ||
| 814 | int neg = 0; | ||
| 815 | int i; | ||
| 816 | |||
| 817 | if (cnt > 63) | ||
| 818 | cnt = 63; | ||
| 819 | |||
| 820 | if (copy_from_user(&buf, ubuf, cnt)) | ||
| 821 | return -EFAULT; | ||
| 822 | |||
| 823 | buf[cnt] = 0; | ||
| 824 | |||
| 825 | if (strncmp(buf, "no_", 3) == 0) { | ||
| 826 | neg = 1; | ||
| 827 | cmp += 3; | ||
| 828 | } | ||
| 829 | |||
| 830 | for (i = 0; sched_feat_names[i]; i++) { | ||
| 831 | int len = strlen(sched_feat_names[i]); | ||
| 832 | |||
| 833 | if (strncmp(cmp, sched_feat_names[i], len) == 0) { | ||
| 834 | if (neg) | ||
| 835 | sysctl_sched_features &= ~(1UL << i); | ||
| 836 | else | ||
| 837 | sysctl_sched_features |= (1UL << i); | ||
| 838 | break; | ||
| 839 | } | ||
| 840 | } | ||
| 841 | |||
| 842 | if (!sched_feat_names[i]) | ||
| 843 | return -EINVAL; | ||
| 844 | |||
| 845 | filp->f_pos += cnt; | ||
| 846 | |||
| 847 | return cnt; | ||
| 848 | } | ||
| 849 | |||
| 850 | static struct file_operations sched_feat_fops = { | ||
| 851 | .open = sched_feat_open, | ||
| 852 | .read = sched_feat_read, | ||
| 853 | .write = sched_feat_write, | ||
| 854 | }; | ||
| 855 | |||
| 856 | static __init int sched_init_debug(void) | ||
| 857 | { | ||
| 858 | int i, j, len; | ||
| 859 | |||
| 860 | for (i = 0; sched_feat_names[i]; i++) { | ||
| 861 | len = strlen(sched_feat_names[i]); | ||
| 862 | |||
| 863 | for (j = 0; j < len; j++) { | ||
| 864 | sched_feat_names[i][j] = | ||
| 865 | tolower(sched_feat_names[i][j]); | ||
| 866 | } | ||
| 867 | } | ||
| 868 | |||
| 869 | debugfs_create_file("sched_features", 0644, NULL, NULL, | ||
| 870 | &sched_feat_fops); | ||
| 871 | |||
| 872 | return 0; | ||
| 873 | } | ||
| 874 | late_initcall(sched_init_debug); | ||
| 875 | |||
| 876 | #endif | ||
| 877 | |||
| 878 | #define sched_feat(x) (sysctl_sched_features & (1UL << __SCHED_FEAT_##x)) | ||
| 761 | 879 | ||
| 762 | /* | 880 | /* |
| 763 | * Number of tasks to iterate in a single balance run. | 881 | * Number of tasks to iterate in a single balance run. |
diff --git a/kernel/sched_features.h b/kernel/sched_features.h new file mode 100644 index 000000000000..1c7283cb9581 --- /dev/null +++ b/kernel/sched_features.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | SCHED_FEAT(NEW_FAIR_SLEEPERS, 1) | ||
| 2 | SCHED_FEAT(WAKEUP_PREEMPT, 1) | ||
| 3 | SCHED_FEAT(START_DEBIT, 1) | ||
| 4 | SCHED_FEAT(AFFINE_WAKEUPS, 1) | ||
| 5 | SCHED_FEAT(CACHE_HOT_BUDDY, 1) | ||
| 6 | SCHED_FEAT(SYNC_WAKEUPS, 1) | ||
| 7 | SCHED_FEAT(HRTICK, 1) | ||
| 8 | SCHED_FEAT(DOUBLE_TICK, 0) | ||
| 9 | SCHED_FEAT(NORMALIZED_SLEEPER, 1) | ||
| 10 | SCHED_FEAT(DEADLINE, 1) | ||
