diff options
author | Kevin Hilman <khilman@linaro.org> | 2015-08-04 14:40:50 -0700 |
---|---|---|
committer | Kevin Hilman <khilman@linaro.org> | 2015-08-04 14:40:50 -0700 |
commit | a06f7d9e6f2702b2726f43ecd1f9808d56e39630 (patch) | |
tree | a28465486c2f6015e0a6cf6f1c5387f753fff26c | |
parent | 56f9fcf4b64cc418ea7c1524d17a3f1788c5112f (diff) | |
parent | c44a699d96df2e13467fc081bff88b97dcc5afb2 (diff) |
Merge branch 'android-3.18' of https://android.googlesource.com/kernel/common into linux-linaro-lsk-v3.18-android
* 'android-3.18' of https://android.googlesource.com/kernel/common:
usb: gadget: fix NULL ptr derefer while symlinking PTP func
uid_cputime: Iterates over all the threads instead of processes.
Fix generic cgroup subsystem permission checks
uid_cputime: fix cputime overflow
usb:gadget:Add "state" attribute to android_device
cpufreq_stats: fix use of cpufreq_for_each_valid_entry() iterator
initramfs: Add skip_initramfs command line option
cpu_power: Avoids race condition when the task exits.
uid_cputime: Avoids double accounting of process stime, utime and cpu_power in task exit.
Shrink ashmem directly through shmem_fallocate
-rw-r--r-- | drivers/cpufreq/cpufreq_stats.c | 3 | ||||
-rw-r--r-- | drivers/misc/uid_cputime.c | 22 | ||||
-rw-r--r-- | drivers/staging/android/ashmem.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/configfs.c | 71 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_mtp.c | 18 | ||||
-rw-r--r-- | drivers/usb/gadget/functions.c | 2 | ||||
-rw-r--r-- | include/linux/initramfs.h | 32 | ||||
-rw-r--r-- | init/Makefile | 3 | ||||
-rw-r--r-- | init/initramfs.c | 19 | ||||
-rw-r--r-- | init/noinitramfs.c | 9 | ||||
-rw-r--r-- | kernel/cgroup.c | 1 |
11 files changed, 165 insertions, 17 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index a460217b513c..a2f1d41820b8 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -140,7 +140,8 @@ void acct_update_power(struct task_struct *task, cputime_t cputime) { return; curr = powerstats->curr[stats->last_index]; - task->cpu_power += curr * cputime_to_usecs(cputime); + if (task->cpu_power != ULLONG_MAX) + task->cpu_power += curr * cputime_to_usecs(cputime); } EXPORT_SYMBOL_GPL(acct_update_power); diff --git a/drivers/misc/uid_cputime.c b/drivers/misc/uid_cputime.c index 89bfba6c5b6a..43298a43ecc3 100644 --- a/drivers/misc/uid_cputime.c +++ b/drivers/misc/uid_cputime.c @@ -75,7 +75,7 @@ static struct uid_entry *find_or_register_uid(uid_t uid) static int uid_stat_show(struct seq_file *m, void *v) { struct uid_entry *uid_entry; - struct task_struct *task; + struct task_struct *task, *temp; cputime_t utime; cputime_t stime; unsigned long bkt; @@ -89,7 +89,7 @@ static int uid_stat_show(struct seq_file *m, void *v) } read_lock(&tasklist_lock); - for_each_process(task) { + do_each_thread(temp, task) { uid_entry = find_or_register_uid(from_kuid_munged( current_user_ns(), task_uid(task))); if (!uid_entry) { @@ -100,11 +100,16 @@ static int uid_stat_show(struct seq_file *m, void *v) task_uid(task))); return -ENOMEM; } + /* if this task is exiting, we have already accounted for the + * time and power. + */ + if (task->cpu_power == ULLONG_MAX) + continue; task_cputime_adjusted(task, &utime, &stime); uid_entry->active_utime += utime; uid_entry->active_stime += stime; uid_entry->active_power += task->cpu_power; - } + } while_each_thread(temp, task); read_unlock(&tasklist_lock); hash_for_each(hash_table, bkt, uid_entry, hash) { @@ -114,10 +119,12 @@ static int uid_stat_show(struct seq_file *m, void *v) uid_entry->active_stime; unsigned long long total_power = uid_entry->power + uid_entry->active_power; - seq_printf(m, "%d: %u %u %llu\n", uid_entry->uid, - cputime_to_usecs(total_utime), - cputime_to_usecs(total_stime), - total_power); + seq_printf(m, "%d: %llu %llu %llu\n", uid_entry->uid, + (unsigned long long)jiffies_to_msecs( + cputime_to_jiffies(total_utime)) * USEC_PER_MSEC, + (unsigned long long)jiffies_to_msecs( + cputime_to_jiffies(total_stime)) * USEC_PER_MSEC, + total_power); } mutex_unlock(&uid_lock); @@ -211,6 +218,7 @@ static int process_notifier(struct notifier_block *self, uid_entry->utime += utime; uid_entry->stime += stime; uid_entry->power += task->cpu_power; + task->cpu_power = ULLONG_MAX; exit: mutex_unlock(&uid_lock); diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index bd8ee37cadee..afee619b7c1b 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -440,7 +440,7 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) loff_t start = range->pgstart * PAGE_SIZE; loff_t end = (range->pgend + 1) * PAGE_SIZE; - do_fallocate(range->asma->file, + range->asma->file->f_op->fallocate(range->asma->file, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, start, end - start); range->purged = ASHMEM_WAS_PURGED; diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 0ad2aa7338da..1157a532a34d 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -436,6 +436,11 @@ static int config_usb_cfg_link( } f = usb_get_function(fi); + if (f == NULL) { + /* Are we trying to symlink PTP without MTP function? */ + ret = -EINVAL; /* Invalid Configuration */ + goto out; + } if (IS_ERR(f)) { ret = PTR_ERR(f); goto out; @@ -1608,11 +1613,49 @@ static const struct usb_gadget_driver configfs_driver_template = { }, }; +#ifdef CONFIG_USB_CONFIGFS_UEVENT +static ssize_t state_show(struct device *pdev, struct device_attribute *attr, + char *buf) +{ + struct gadget_info *dev = dev_get_drvdata(pdev); + struct usb_composite_dev *cdev; + char *state = "DISCONNECTED"; + unsigned long flags; + + if (!dev) + goto out; + + cdev = &dev->cdev; + + if (!cdev) + goto out; + + spin_lock_irqsave(&cdev->lock, flags); + if (cdev->config) + state = "CONFIGURED"; + else if (dev->connected) + state = "CONNECTED"; + spin_unlock_irqrestore(&cdev->lock, flags); +out: + return sprintf(buf, "%s\n", state); +} + +static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); + +static struct device_attribute *android_usb_attributes[] = { + &dev_attr_state, + NULL +}; +#endif + static struct config_group *gadgets_make( struct config_group *group, const char *name) { struct gadget_info *gi; + struct device_attribute **attrs; + struct device_attribute *attr; + int err; gi = kzalloc(sizeof(*gi), GFP_KERNEL); if (!gi) @@ -1658,10 +1701,19 @@ static struct config_group *gadgets_make( MKDEV(0, 0), NULL, "android0"); if (IS_ERR(android_device)) goto err; + + dev_set_drvdata(android_device, gi); + + attrs = android_usb_attributes; + while ((attr = *attrs++)) { + err = device_create_file(android_device, attr); + if (err) + goto err1; + } #endif if (!gi->composite.gadget_driver.function) - goto err; + goto err1; #ifdef CONFIG_USB_OTG gi->otg.bLength = sizeof(struct usb_otg_descriptor); @@ -1672,6 +1724,16 @@ static struct config_group *gadgets_make( config_group_init_type_name(&gi->group, name, &gadget_root_type); return &gi->group; + +err1: +#ifdef CONFIG_USB_CONFIGFS_UEVENT + attrs = android_usb_attributes; + while ((attr = *attrs++)) + device_remove_file(android_device, attr); + + device_destroy(android_device->class, + android_device->devt); +#endif err: kfree(gi); return ERR_PTR(-ENOMEM); @@ -1679,8 +1741,15 @@ err: static void gadgets_drop(struct config_group *group, struct config_item *item) { + struct device_attribute **attrs; + struct device_attribute *attr; + config_item_put(item); + #ifdef CONFIG_USB_CONFIGFS_UEVENT + attrs = android_usb_attributes; + while ((attr = *attrs++)) + device_remove_file(android_device, attr); device_destroy(android_device->class, android_device->devt); #endif } diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c index 82f6b2ebaebb..03a61f8b9d48 100644 --- a/drivers/usb/gadget/function/f_mtp.c +++ b/drivers/usb/gadget/function/f_mtp.c @@ -1426,8 +1426,24 @@ struct usb_function *function_alloc_mtp_ptp(struct usb_function_instance *fi, bool mtp_config) { struct mtp_instance *fi_mtp = to_fi_mtp(fi); - struct mtp_dev *dev = fi_mtp->dev; + struct mtp_dev *dev; + + /* + * PTP piggybacks on MTP function so make sure we have + * created MTP function before we associate this PTP + * function with a gadget configuration. + */ + if (fi_mtp->dev == NULL) { + pr_err("Error: Create MTP function before linking" + " PTP function with a gadget configuration\n"); + pr_err("\t1: Delete existing PTP function if any\n"); + pr_err("\t2: Create MTP function\n"); + pr_err("\t3: Create and symlink PTP function" + " with a gadget configuration\n"); + return NULL; + } + dev = fi_mtp->dev; dev->function.name = DRIVER_NAME; dev->function.strings = mtp_strings; if (mtp_config) { diff --git a/drivers/usb/gadget/functions.c b/drivers/usb/gadget/functions.c index b13f839e7368..389c1f3d0fee 100644 --- a/drivers/usb/gadget/functions.c +++ b/drivers/usb/gadget/functions.c @@ -58,7 +58,7 @@ struct usb_function *usb_get_function(struct usb_function_instance *fi) struct usb_function *f; f = fi->fd->alloc_func(fi); - if (IS_ERR(f)) + if ((f == NULL) || IS_ERR(f)) return f; f->fi = fi; return f; diff --git a/include/linux/initramfs.h b/include/linux/initramfs.h new file mode 100644 index 000000000000..fc7da63b125b --- /dev/null +++ b/include/linux/initramfs.h @@ -0,0 +1,32 @@ +/* + * include/linux/initramfs.h + * + * Copyright (C) 2015, Google + * Rom Lemarchand <romlem@android.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LINUX_INITRAMFS_H +#define _LINUX_INITRAMFS_H + +#include <linux/kconfig.h> + +#if IS_BUILTIN(CONFIG_BLK_DEV_INITRD) + +int __init default_rootfs(void); + +#endif + +#endif /* _LINUX_INITRAMFS_H */ diff --git a/init/Makefile b/init/Makefile index 7bc47ee31c36..692b91f1c1d4 100644 --- a/init/Makefile +++ b/init/Makefile @@ -3,11 +3,8 @@ # obj-y := main.o version.o mounts.o -ifneq ($(CONFIG_BLK_DEV_INITRD),y) obj-y += noinitramfs.o -else obj-$(CONFIG_BLK_DEV_INITRD) += initramfs.o -endif obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o ifneq ($(CONFIG_ARCH_INIT_TASK),y) diff --git a/init/initramfs.c b/init/initramfs.c index ad1bd7787bbb..d39079e690fa 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -18,6 +18,7 @@ #include <linux/dirent.h> #include <linux/syscalls.h> #include <linux/utime.h> +#include <linux/initramfs.h> static ssize_t __init xwrite(int fd, const char *p, size_t count) { @@ -605,9 +606,25 @@ static void __init clean_rootfs(void) } #endif +static int __initdata do_skip_initramfs; + +static int __init skip_initramfs_param(char *str) +{ + if (*str) + return 0; + do_skip_initramfs = 1; + return 1; +} +__setup("skip_initramfs", skip_initramfs_param); + static int __init populate_rootfs(void) { - char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size); + char *err; + + if (do_skip_initramfs) + return default_rootfs(); + + err = unpack_to_rootfs(__initramfs_start, __initramfs_size); if (err) panic("%s", err); /* Failed to decompress INTERNAL initramfs */ if (initrd_start) { diff --git a/init/noinitramfs.c b/init/noinitramfs.c index 267739d85179..bcc8bcb053ee 100644 --- a/init/noinitramfs.c +++ b/init/noinitramfs.c @@ -21,11 +21,16 @@ #include <linux/stat.h> #include <linux/kdev_t.h> #include <linux/syscalls.h> +#include <linux/kconfig.h> +#include <linux/initramfs.h> /* * Create a simple rootfs that is similar to the default initramfs */ -static int __init default_rootfs(void) +#if !IS_BUILTIN(CONFIG_BLK_DEV_INITRD) +static +#endif +int __init default_rootfs(void) { int err; @@ -49,4 +54,6 @@ out: printk(KERN_WARNING "Failed to create a rootfs\n"); return err; } +#if !IS_BUILTIN(CONFIG_BLK_DEV_INITRD) rootfs_initcall(default_rootfs); +#endif diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 12b3899ce908..30f180112922 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2416,6 +2416,7 @@ retry_find_task: cset = task_css_set(tsk); list_add(&cset->mg_node, &tset.src_csets); ret = cgroup_allow_attach(cgrp, &tset); + list_del(&tset.src_csets); if (ret) { rcu_read_unlock(); goto out_unlock_cgroup; |