mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branches 'pm-runtime', 'pm-sleep' and 'pm-tools' into linux-next
* pm-runtime: PM: runtime: Only set runtime_error on suspend callback failures * pm-sleep: PM: sleep: Allow disabling DPM watchdog by default PM: sleep: Rename module parameters prefix to "pm" PM: hibernate: swap: defer linking the next map page PM: hibernate: Fix memory leak in snapshot_write_next() error path PM: hibernate: Use %pe to print error pointer values PM: hibernate: Remove kernel-doc markings from helper descriptions PM: sleep: Fix off-by-one in wakelocks number limit check * pm-tools: tools/power: intel_pstate_tracer: avoid optional imports for help
This commit is contained in:
@@ -47,6 +47,7 @@
|
||||
PCI PCI bus support is enabled.
|
||||
PCIE PCI Express support is enabled.
|
||||
PCMCIA The PCMCIA subsystem is enabled.
|
||||
PM Power Management support is enabled.
|
||||
PNP Plug & Play support is enabled.
|
||||
PPC PowerPC architecture is enabled.
|
||||
PPT Parallel port support is enabled.
|
||||
@@ -5354,6 +5355,12 @@ Kernel parameters
|
||||
pm_debug_messages [SUSPEND,KNL]
|
||||
Enable suspend/resume debug messages during boot up.
|
||||
|
||||
pm.dpm_watchdog_enabled=
|
||||
[PM] Enable or disable the DPM watchdog. Requires
|
||||
CONFIG_PM_SLEEP and CONFIG_DPM_WATCHDOG enabled.
|
||||
Format: <bool>
|
||||
Default value is set by CONFIG_DPM_WATCHDOG_ENABLED.
|
||||
|
||||
pnp.debug=1 [PNP]
|
||||
Enable PNP debug messages (depends on the
|
||||
CONFIG_PNP_DEBUG_MESSAGES option). Change at run-time
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
#include "../base.h"
|
||||
#include "power.h"
|
||||
|
||||
#undef MODULE_PARAM_PREFIX
|
||||
#define MODULE_PARAM_PREFIX "pm."
|
||||
|
||||
typedef int (*pm_callback_t)(struct device *);
|
||||
|
||||
/*
|
||||
@@ -532,6 +535,11 @@ module_param(dpm_watchdog_all_cpu_backtrace, bool, 0644);
|
||||
MODULE_PARM_DESC(dpm_watchdog_all_cpu_backtrace,
|
||||
"Backtrace all CPUs on DPM watchdog timeout");
|
||||
|
||||
static bool __read_mostly dpm_watchdog_enabled =
|
||||
IS_ENABLED(CONFIG_DPM_WATCHDOG_ENABLED);
|
||||
module_param(dpm_watchdog_enabled, bool, 0644);
|
||||
MODULE_PARM_DESC(dpm_watchdog_enabled, "Enable DPM watchdog");
|
||||
|
||||
static unsigned int __read_mostly dpm_watchdog_timeout = CONFIG_DPM_WATCHDOG_TIMEOUT;
|
||||
static unsigned int __read_mostly dpm_watchdog_warning_timeout =
|
||||
CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT;
|
||||
@@ -627,6 +635,9 @@ static void dpm_watchdog_set(struct dpm_watchdog *wd, struct device *dev)
|
||||
{
|
||||
struct timer_list *timer = &wd->timer;
|
||||
|
||||
if (!dpm_watchdog_enabled)
|
||||
return;
|
||||
|
||||
wd->dev = dev;
|
||||
wd->tsk = current;
|
||||
wd->fatal = dpm_watchdog_timeout == dpm_watchdog_warning_timeout;
|
||||
@@ -645,6 +656,9 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd)
|
||||
{
|
||||
struct timer_list *timer = &wd->timer;
|
||||
|
||||
if (!dpm_watchdog_enabled)
|
||||
return;
|
||||
|
||||
timer_delete_sync(timer);
|
||||
timer_destroy_on_stack(timer);
|
||||
}
|
||||
|
||||
@@ -469,9 +469,6 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
|
||||
if (retval == -EACCES)
|
||||
retval = -EAGAIN;
|
||||
|
||||
if (retval != -EAGAIN && retval != -EBUSY)
|
||||
dev->power.runtime_error = retval;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -751,6 +748,9 @@ static int rpm_suspend(struct device *dev, int rpmflags)
|
||||
dev->power.deferred_resume = false;
|
||||
wake_up_all(&dev->power.wait_queue);
|
||||
|
||||
if (retval != -EAGAIN && retval != -EBUSY)
|
||||
dev->power.runtime_error = retval;
|
||||
|
||||
/*
|
||||
* On transient errors, if the callback routine failed an autosuspend,
|
||||
* and if the last_busy time has been updated so that there is a new
|
||||
|
||||
@@ -268,6 +268,16 @@ config DPM_WATCHDOG
|
||||
captured in pstore device for inspection in subsequent
|
||||
boot session.
|
||||
|
||||
config DPM_WATCHDOG_ENABLED
|
||||
bool "Enable DPM watchdog by default"
|
||||
depends on DPM_WATCHDOG
|
||||
default y
|
||||
help
|
||||
If you say Y here, the DPM watchdog will be enabled by default.
|
||||
If you say N, it will be compiled in but disabled. It can be
|
||||
enabled at boot time via the "pm.dpm_watchdog_enabled" kernel
|
||||
parameter or at runtime via sysfs.
|
||||
|
||||
config DPM_WATCHDOG_TIMEOUT
|
||||
int "Watchdog timeout to panic in seconds"
|
||||
range 1 120
|
||||
|
||||
+24
-23
@@ -458,7 +458,7 @@ static struct rtree_node *alloc_rtree_node(gfp_t gfp_mask, int safe_needed,
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* add_rtree_block - Add a new leave node to the radix tree.
|
||||
*
|
||||
* The leave nodes need to be allocated in order to keep the leaves
|
||||
@@ -528,7 +528,7 @@ static int add_rtree_block(struct mem_zone_bm_rtree *zone, gfp_t gfp_mask,
|
||||
static void free_zone_bm_rtree(struct mem_zone_bm_rtree *zone,
|
||||
int clear_nosave_free);
|
||||
|
||||
/**
|
||||
/*
|
||||
* create_zone_bm_rtree - Create a radix tree for one zone.
|
||||
*
|
||||
* Allocated the mem_zone_bm_rtree structure and initializes it.
|
||||
@@ -566,7 +566,7 @@ static struct mem_zone_bm_rtree *create_zone_bm_rtree(gfp_t gfp_mask,
|
||||
return zone;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* free_zone_bm_rtree - Free the memory of the radix tree.
|
||||
*
|
||||
* Free all node pages of the radix tree. The mem_zone_bm_rtree
|
||||
@@ -678,7 +678,7 @@ static int create_mem_extents(struct list_head *list, gfp_t gfp_mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* memory_bm_create - Allocate memory for a memory bitmap.
|
||||
*/
|
||||
static int memory_bm_create(struct memory_bitmap *bm, gfp_t gfp_mask,
|
||||
@@ -720,7 +720,7 @@ static int memory_bm_create(struct memory_bitmap *bm, gfp_t gfp_mask,
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* memory_bm_free - Free memory occupied by the memory bitmap.
|
||||
* @bm: Memory bitmap.
|
||||
*/
|
||||
@@ -736,7 +736,7 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free)
|
||||
INIT_LIST_HEAD(&bm->zones);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* memory_bm_find_bit - Find the bit for a given PFN in a memory bitmap.
|
||||
*
|
||||
* Find the bit in memory bitmap @bm that corresponds to the given PFN.
|
||||
@@ -988,7 +988,7 @@ static void memory_bm_recycle(struct memory_bitmap *bm)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* register_nosave_region - Register a region of unsaveable memory.
|
||||
*
|
||||
* Register a range of page frames the contents of which should not be saved
|
||||
@@ -1305,7 +1305,7 @@ static unsigned int count_free_highmem_pages(void)
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* saveable_highmem_page - Check if a highmem page is saveable.
|
||||
*
|
||||
* Determine whether a highmem page should be included in a hibernation image.
|
||||
@@ -1362,7 +1362,7 @@ static unsigned int count_highmem_pages(void)
|
||||
}
|
||||
#endif /* CONFIG_HIGHMEM */
|
||||
|
||||
/**
|
||||
/*
|
||||
* saveable_page - Check if the given page is saveable.
|
||||
*
|
||||
* Determine whether a non-highmem page should be included in a hibernation
|
||||
@@ -1440,7 +1440,7 @@ static inline bool do_copy_page(long *dst, long *src)
|
||||
return !z;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* safe_copy_page - Copy a page in a safe way.
|
||||
*
|
||||
* Check if the page we are going to copy is marked as present in the kernel
|
||||
@@ -1687,7 +1687,7 @@ static unsigned long preallocate_image_highmem(unsigned long nr_pages)
|
||||
return preallocate_image_pages(nr_pages, GFP_IMAGE | __GFP_HIGHMEM);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* __fraction - Compute (an approximation of) x * (multiplier / base).
|
||||
*/
|
||||
static unsigned long __fraction(u64 x, u64 multiplier, u64 base)
|
||||
@@ -1982,7 +1982,7 @@ int hibernate_preallocate_memory(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
/**
|
||||
/*
|
||||
* count_pages_for_highmem - Count non-highmem pages needed for copying highmem.
|
||||
*
|
||||
* Compute the number of non-highmem pages that will be necessary for creating
|
||||
@@ -2003,7 +2003,7 @@ static unsigned int count_pages_for_highmem(unsigned int nr_highmem)
|
||||
static unsigned int count_pages_for_highmem(unsigned int nr_highmem) { return 0; }
|
||||
#endif /* CONFIG_HIGHMEM */
|
||||
|
||||
/**
|
||||
/*
|
||||
* enough_free_mem - Check if there is enough free memory for the image.
|
||||
*/
|
||||
static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem)
|
||||
@@ -2023,7 +2023,7 @@ static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
/**
|
||||
/*
|
||||
* get_highmem_buffer - Allocate a buffer for highmem pages.
|
||||
*
|
||||
* If there are some highmem pages in the hibernation image, we may need a
|
||||
@@ -2035,7 +2035,7 @@ static inline int get_highmem_buffer(int safe_needed)
|
||||
return buffer ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* alloc_highmem_pages - Allocate some highmem pages for the image.
|
||||
*
|
||||
* Try to allocate as many pages as needed, but if the number of free highmem
|
||||
@@ -2065,7 +2065,7 @@ static inline unsigned int alloc_highmem_pages(struct memory_bitmap *bm,
|
||||
unsigned int n) { return 0; }
|
||||
#endif /* CONFIG_HIGHMEM */
|
||||
|
||||
/**
|
||||
/*
|
||||
* swsusp_alloc - Allocate memory for hibernation image.
|
||||
*
|
||||
* We first try to allocate as many highmem pages as there are
|
||||
@@ -2292,7 +2292,7 @@ static void duplicate_memory_bitmap(struct memory_bitmap *dst,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* mark_unsafe_pages - Mark pages that were used before hibernation.
|
||||
*
|
||||
* Mark the pages that cannot be used for storing the image during restoration,
|
||||
@@ -2330,7 +2330,7 @@ static int check_header(struct swsusp_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* load_header - Check the image header and copy the data from it.
|
||||
*/
|
||||
static int load_header(struct swsusp_info *info)
|
||||
@@ -2483,7 +2483,7 @@ static int prepare_highmem_image(struct memory_bitmap *bm,
|
||||
|
||||
static struct page *last_highmem_page;
|
||||
|
||||
/**
|
||||
/*
|
||||
* get_highmem_page_buffer - Prepare a buffer to store a highmem image page.
|
||||
*
|
||||
* For a given highmem image page get a buffer that suspend_write_next() should
|
||||
@@ -2706,7 +2706,7 @@ static int prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm,
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* get_buffer - Get the address to store the next image data page.
|
||||
*
|
||||
* Get the address that snapshot_write_next() should return to its caller to
|
||||
@@ -2797,9 +2797,10 @@ next:
|
||||
return error;
|
||||
|
||||
error = memory_bm_create(&zero_bm, GFP_ATOMIC, PG_ANY);
|
||||
if (error)
|
||||
if (error) {
|
||||
memory_bm_free(©_bm, PG_UNSAFE_CLEAR);
|
||||
return error;
|
||||
|
||||
}
|
||||
nr_zero_pages = 0;
|
||||
|
||||
hibernate_restore_protection_begin();
|
||||
@@ -2843,7 +2844,7 @@ next:
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* snapshot_write_finalize - Complete the loading of a hibernation image.
|
||||
*
|
||||
* Must be called after the last call to snapshot_write_next() in case the last
|
||||
|
||||
+22
-12
@@ -430,19 +430,22 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf,
|
||||
|
||||
if (!handle->cur)
|
||||
return -EINVAL;
|
||||
offset = alloc_swapdev_block(root_swap);
|
||||
error = write_page(buf, offset, hb);
|
||||
if (error)
|
||||
return error;
|
||||
handle->cur->entries[handle->k++] = offset;
|
||||
|
||||
/*
|
||||
* If the current map page is full, allocate and link next one first.
|
||||
* Delaying this until here avoids writing an empty swap map page when
|
||||
* the image size is an exact MAP_PAGE_ENTRIES multiple.
|
||||
*/
|
||||
if (handle->k >= MAP_PAGE_ENTRIES) {
|
||||
offset = alloc_swapdev_block(root_swap);
|
||||
if (!offset)
|
||||
return -ENOSPC;
|
||||
|
||||
handle->cur->next_swap = offset;
|
||||
error = write_page(handle->cur, handle->cur_swap, hb);
|
||||
if (error)
|
||||
goto out;
|
||||
return error;
|
||||
|
||||
clear_page(handle->cur);
|
||||
handle->cur_swap = offset;
|
||||
handle->k = 0;
|
||||
@@ -450,7 +453,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf,
|
||||
if (hb && low_free_pages() <= handle->reqd_free_pages) {
|
||||
error = hib_wait_io(hb);
|
||||
if (error)
|
||||
goto out;
|
||||
return error;
|
||||
/*
|
||||
* Recalculate the number of required free pages, to
|
||||
* make sure we never take more than half.
|
||||
@@ -458,14 +461,21 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf,
|
||||
handle->reqd_free_pages = reqd_free_pages();
|
||||
}
|
||||
}
|
||||
out:
|
||||
return error;
|
||||
|
||||
offset = alloc_swapdev_block(root_swap);
|
||||
error = write_page(buf, offset, hb);
|
||||
if (error)
|
||||
return error;
|
||||
handle->cur->entries[handle->k++] = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flush_swap_writer(struct swap_map_handle *handle)
|
||||
{
|
||||
if (handle->cur && handle->cur_swap)
|
||||
if (handle->cur && handle->cur_swap && handle->k)
|
||||
return write_page(handle->cur, handle->cur_swap, NULL);
|
||||
else if (handle->cur && handle->cur_swap)
|
||||
return 0;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -739,7 +749,7 @@ static int save_compressed_image(struct swap_map_handle *handle,
|
||||
|
||||
data[thr].cc = crypto_alloc_acomp(hib_comp_algo, 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR_OR_NULL(data[thr].cc)) {
|
||||
pr_err("Could not allocate comp stream %ld\n", PTR_ERR(data[thr].cc));
|
||||
pr_err("Could not allocate comp stream %pe\n", data[thr].cc);
|
||||
ret = -EFAULT;
|
||||
goto out_clean;
|
||||
}
|
||||
@@ -1243,7 +1253,7 @@ static int load_compressed_image(struct swap_map_handle *handle,
|
||||
|
||||
data[thr].cc = crypto_alloc_acomp(hib_comp_algo, 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR_OR_NULL(data[thr].cc)) {
|
||||
pr_err("Could not allocate comp stream %ld\n", PTR_ERR(data[thr].cc));
|
||||
pr_err("Could not allocate comp stream %pe\n", data[thr].cc);
|
||||
ret = -EFAULT;
|
||||
goto out_clean;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ static unsigned int number_of_wakelocks;
|
||||
|
||||
static inline bool wakelocks_limit_exceeded(void)
|
||||
{
|
||||
return number_of_wakelocks > CONFIG_PM_WAKELOCKS_LIMIT;
|
||||
return number_of_wakelocks >= CONFIG_PM_WAKELOCKS_LIMIT;
|
||||
}
|
||||
|
||||
static inline void increment_wakelocks_number(void)
|
||||
|
||||
@@ -32,8 +32,6 @@ import re
|
||||
import signal
|
||||
import sys
|
||||
import getopt
|
||||
import Gnuplot
|
||||
from numpy import *
|
||||
from decimal import *
|
||||
|
||||
__author__ = "Srinivas Pandruvada"
|
||||
@@ -88,8 +86,8 @@ def print_help(driver_name):
|
||||
print(' kbytes: Kilo bytes of memory per CPU to allocate to the trace buffer. Default: 10240')
|
||||
print(' Output:')
|
||||
print(' If not already present, creates a "results/test_name" folder in the current working directory with:')
|
||||
print(' cpu.csv - comma seperated values file with trace contents and some additional calculations.')
|
||||
print(' cpu???.csv - comma seperated values file for CPU number ???.')
|
||||
print(' cpu.csv - comma separated values file with trace contents and some additional calculations.')
|
||||
print(' cpu???.csv - comma separated values file for CPU number ???.')
|
||||
print(' *.png - a variety of PNG format plot files created from the trace contents and the additional calculations.')
|
||||
print(' Notes:')
|
||||
print(' Avoid the use of _ (underscore) in test names, because in gnuplot it is a subscript directive.')
|
||||
@@ -295,6 +293,8 @@ def common_all_gnuplot_settings(output_png):
|
||||
def common_gnuplot_settings():
|
||||
""" common gnuplot settings. """
|
||||
|
||||
import Gnuplot
|
||||
|
||||
g_plot = Gnuplot.Gnuplot(persist=1)
|
||||
# The following line is for rigor only. It seems to be assumed for .csv files
|
||||
g_plot('set datafile separator \",\"')
|
||||
@@ -343,7 +343,7 @@ def store_csv(cpu_int, time_pre_dec, time_post_dec, core_busy, scaled, _from, _t
|
||||
graph_data_present = True;
|
||||
|
||||
def split_csv(current_max_cpu, cpu_mask):
|
||||
""" seperate the all csv file into per CPU csv files. """
|
||||
""" separate the main csv file into per CPU csv files. """
|
||||
|
||||
if os.path.exists('cpu.csv'):
|
||||
for index in range(0, current_max_cpu + 1):
|
||||
@@ -482,7 +482,7 @@ def read_trace_data(filename, cpu_mask):
|
||||
if cpu_int > current_max_cpu:
|
||||
current_max_cpu = cpu_int
|
||||
# End of for each trace line loop
|
||||
# Now seperate the main overall csv file into per CPU csv files.
|
||||
# Now separate the main overall csv file into per CPU csv files.
|
||||
split_csv(current_max_cpu, cpu_mask)
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
@@ -508,8 +508,6 @@ if __name__ == "__main__":
|
||||
valid1 = False
|
||||
valid2 = False
|
||||
|
||||
cpu_mask = zeros((MAX_CPUS,), dtype=int)
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:],"ht:i:c:n:m:",["help","trace_file=","interval=","cpu=","name=","memory="])
|
||||
except getopt.GetoptError:
|
||||
@@ -538,6 +536,10 @@ if __name__ == "__main__":
|
||||
print_help('intel_pstate')
|
||||
sys.exit()
|
||||
|
||||
from numpy import zeros
|
||||
|
||||
cpu_mask = zeros((MAX_CPUS,), dtype=int)
|
||||
|
||||
if cpu_list:
|
||||
for p in re.split("[,]", cpu_list):
|
||||
if int(p) < MAX_CPUS :
|
||||
|
||||
Reference in New Issue
Block a user