@@ -873,6 +873,113 @@ static const struct file_operations proc_environ_operations = {
873
873
.release = mem_release ,
874
874
};
875
875
876
+ static ssize_t oom_adj_read (struct file * file , char __user * buf , size_t count ,
877
+ loff_t * ppos )
878
+ {
879
+ struct task_struct * task = get_proc_task (file -> f_path .dentry -> d_inode );
880
+ char buffer [PROC_NUMBUF ];
881
+ int oom_adj = OOM_ADJUST_MIN ;
882
+ size_t len ;
883
+ unsigned long flags ;
884
+
885
+ if (!task )
886
+ return - ESRCH ;
887
+ if (lock_task_sighand (task , & flags )) {
888
+ if (task -> signal -> oom_score_adj == OOM_SCORE_ADJ_MAX )
889
+ oom_adj = OOM_ADJUST_MAX ;
890
+ else
891
+ oom_adj = (task -> signal -> oom_score_adj * - OOM_DISABLE ) /
892
+ OOM_SCORE_ADJ_MAX ;
893
+ unlock_task_sighand (task , & flags );
894
+ }
895
+ put_task_struct (task );
896
+ len = snprintf (buffer , sizeof (buffer ), "%d\n" , oom_adj );
897
+ return simple_read_from_buffer (buf , count , ppos , buffer , len );
898
+ }
899
+
900
+ static ssize_t oom_adj_write (struct file * file , const char __user * buf ,
901
+ size_t count , loff_t * ppos )
902
+ {
903
+ struct task_struct * task ;
904
+ char buffer [PROC_NUMBUF ];
905
+ int oom_adj ;
906
+ unsigned long flags ;
907
+ int err ;
908
+
909
+ memset (buffer , 0 , sizeof (buffer ));
910
+ if (count > sizeof (buffer ) - 1 )
911
+ count = sizeof (buffer ) - 1 ;
912
+ if (copy_from_user (buffer , buf , count )) {
913
+ err = - EFAULT ;
914
+ goto out ;
915
+ }
916
+
917
+ err = kstrtoint (strstrip (buffer ), 0 , & oom_adj );
918
+ if (err )
919
+ goto out ;
920
+ if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX ) &&
921
+ oom_adj != OOM_DISABLE ) {
922
+ err = - EINVAL ;
923
+ goto out ;
924
+ }
925
+
926
+ task = get_proc_task (file -> f_path .dentry -> d_inode );
927
+ if (!task ) {
928
+ err = - ESRCH ;
929
+ goto out ;
930
+ }
931
+
932
+ task_lock (task );
933
+ if (!task -> mm ) {
934
+ err = - EINVAL ;
935
+ goto err_task_lock ;
936
+ }
937
+
938
+ if (!lock_task_sighand (task , & flags )) {
939
+ err = - ESRCH ;
940
+ goto err_task_lock ;
941
+ }
942
+
943
+ /*
944
+ * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
945
+ * value is always attainable.
946
+ */
947
+ if (oom_adj == OOM_ADJUST_MAX )
948
+ oom_adj = OOM_SCORE_ADJ_MAX ;
949
+ else
950
+ oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX ) / - OOM_DISABLE ;
951
+
952
+ if (oom_adj < task -> signal -> oom_score_adj &&
953
+ !capable (CAP_SYS_RESOURCE )) {
954
+ err = - EACCES ;
955
+ goto err_sighand ;
956
+ }
957
+
958
+ /*
959
+ * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
960
+ * /proc/pid/oom_score_adj instead.
961
+ */
962
+ printk_once (KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n" ,
963
+ current -> comm , task_pid_nr (current ), task_pid_nr (task ),
964
+ task_pid_nr (task ));
965
+
966
+ task -> signal -> oom_score_adj = oom_adj ;
967
+ trace_oom_score_adj_update (task );
968
+ err_sighand :
969
+ unlock_task_sighand (task , & flags );
970
+ err_task_lock :
971
+ task_unlock (task );
972
+ put_task_struct (task );
973
+ out :
974
+ return err < 0 ? err : count ;
975
+ }
976
+
977
+ static const struct file_operations proc_oom_adj_operations = {
978
+ .read = oom_adj_read ,
979
+ .write = oom_adj_write ,
980
+ .llseek = generic_file_llseek ,
981
+ };
982
+
876
983
static ssize_t oom_score_adj_read (struct file * file , char __user * buf ,
877
984
size_t count , loff_t * ppos )
878
985
{
@@ -2598,6 +2705,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2598
2705
REG ("cgroup" , S_IRUGO , proc_cgroup_operations ),
2599
2706
#endif
2600
2707
INF ("oom_score" , S_IRUGO , proc_oom_score ),
2708
+ REG ("oom_adj" , S_IRUGO |S_IWUSR , proc_oom_adj_operations ),
2601
2709
REG ("oom_score_adj" , S_IRUGO |S_IWUSR , proc_oom_score_adj_operations ),
2602
2710
#ifdef CONFIG_AUDITSYSCALL
2603
2711
REG ("loginuid" , S_IWUSR |S_IRUGO , proc_loginuid_operations ),
@@ -2964,6 +3072,7 @@ static const struct pid_entry tid_base_stuff[] = {
2964
3072
REG ("cgroup" , S_IRUGO , proc_cgroup_operations ),
2965
3073
#endif
2966
3074
INF ("oom_score" , S_IRUGO , proc_oom_score ),
3075
+ REG ("oom_adj" , S_IRUGO |S_IWUSR , proc_oom_adj_operations ),
2967
3076
REG ("oom_score_adj" , S_IRUGO |S_IWUSR , proc_oom_score_adj_operations ),
2968
3077
#ifdef CONFIG_AUDITSYSCALL
2969
3078
REG ("loginuid" , S_IWUSR |S_IRUGO , proc_loginuid_operations ),
0 commit comments