From 677a0b5ac16337277139798ec43fc32ebaae1347 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 30 Apr 2013 15:26:44 -0700 Subject: drivers/usb/storage/realtek_cr.c: fix build Remove unused local `us', which broke the build. Also nuke an unneeded cast. Repairs commit 191648d03d20 ("usb: storage: Convert US_DEBUGP to usb_stor_dbg"). Cc: Joe Perches Acked-by: David Rientjes Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/usb/storage/realtek_cr.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 4797228747fb..8623577bbbe7 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -933,14 +933,11 @@ static int realtek_cr_autosuspend_setup(struct us_data *us) static void realtek_cr_destructor(void *extra) { - struct rts51x_chip *chip = (struct rts51x_chip *)extra; - struct us_data *us; + struct rts51x_chip *chip = extra; if (!chip) return; - us = chip->us; - #ifdef CONFIG_REALTEK_AUTOPM if (ss_en) { del_timer(&chip->rts51x_suspend_timer); -- cgit v1.2.3-70-g09d2 From 1e01c968db3d0aebd48e31db15f24516b03128df Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 30 Apr 2013 15:26:51 -0700 Subject: frontswap: make frontswap_init use a pointer for the ops This simplifies the code in the frontswap - we can get rid of the 'backend_registered' test and instead check against frontswap_ops. [v1: Rebase on top of 703ba7fe5e0 (ramster->zcache move] Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Bob Liu Cc: Wanpeng Li Cc: Andor Daam Cc: Dan Magenheimer Cc: Florian Schmaus Cc: Minchan Kim Cc: Stefan Hengelein Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/zcache/zcache-main.c | 8 ++++---- drivers/xen/tmem.c | 6 +++--- include/linux/frontswap.h | 2 +- mm/frontswap.c | 38 +++++++++++++++++------------------- 4 files changed, 26 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index e23d814b5392..09c69c8026f9 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1707,9 +1707,9 @@ static struct frontswap_ops zcache_frontswap_ops = { .init = zcache_frontswap_init }; -struct frontswap_ops zcache_frontswap_register_ops(void) +struct frontswap_ops *zcache_frontswap_register_ops(void) { - struct frontswap_ops old_ops = + struct frontswap_ops *old_ops = frontswap_register_ops(&zcache_frontswap_ops); return old_ops; @@ -1874,7 +1874,7 @@ static int __init zcache_init(void) pr_warn("%s: cleancache_ops overridden\n", namestr); } if (zcache_enabled && !disable_frontswap) { - struct frontswap_ops old_ops; + struct frontswap_ops *old_ops; old_ops = zcache_frontswap_register_ops(); if (frontswap_has_exclusive_gets) @@ -1886,7 +1886,7 @@ static int __init zcache_init(void) namestr, frontswap_has_exclusive_gets, !disable_frontswap_ignore_nonactive); #endif - if (old_ops.init != NULL) + if (old_ops != NULL) pr_warn("%s: frontswap_ops overridden\n", namestr); } if (ramster_enabled) diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index 3ee836d42581..7a01a5fd0f63 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c @@ -362,7 +362,7 @@ static int __init no_frontswap(char *s) } __setup("nofrontswap", no_frontswap); -static struct frontswap_ops __initdata tmem_frontswap_ops = { +static struct frontswap_ops tmem_frontswap_ops = { .store = tmem_frontswap_store, .load = tmem_frontswap_load, .invalidate_page = tmem_frontswap_flush_page, @@ -378,11 +378,11 @@ static int __init xen_tmem_init(void) #ifdef CONFIG_FRONTSWAP if (tmem_enabled && use_frontswap) { char *s = ""; - struct frontswap_ops old_ops = + struct frontswap_ops *old_ops = frontswap_register_ops(&tmem_frontswap_ops); tmem_frontswap_poolid = -1; - if (old_ops.init != NULL) + if (old_ops) s = " (WARNING: frontswap_ops overridden)"; printk(KERN_INFO "frontswap enabled, RAM provided by " "Xen Transcendent Memory%s\n", s); diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h index 30442547b9e6..d4f29875c7cc 100644 --- a/include/linux/frontswap.h +++ b/include/linux/frontswap.h @@ -14,7 +14,7 @@ struct frontswap_ops { }; extern bool frontswap_enabled; -extern struct frontswap_ops +extern struct frontswap_ops * frontswap_register_ops(struct frontswap_ops *ops); extern void frontswap_shrink(unsigned long); extern unsigned long frontswap_curr_pages(void); diff --git a/mm/frontswap.c b/mm/frontswap.c index cbd2b8af8129..e44c9cbd1443 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -24,7 +24,7 @@ * frontswap_ops is set by frontswap_register_ops to contain the pointers * to the frontswap "backend" implementation functions. */ -static struct frontswap_ops frontswap_ops __read_mostly; +static struct frontswap_ops *frontswap_ops __read_mostly; /* * This global enablement flag reduces overhead on systems where frontswap_ops @@ -108,41 +108,39 @@ static inline void inc_frontswap_invalidates(void) { } * * The time between the backend being registered and the swap file system * calling the backend (via the frontswap_* functions) is indeterminate as - * backend_registered is not atomic_t (or a value guarded by a spinlock). + * frontswap_ops is not atomic_t (or a value guarded by a spinlock). * That is OK as we are comfortable missing some of these calls to the newly * registered backend. * * Obviously the opposite (unloading the backend) must be done after all * the frontswap_[store|load|invalidate_area|invalidate_page] start - * ignorning or failing the requests - at which point backend_registered + * ignorning or failing the requests - at which point frontswap_ops * would have to be made in some fashion atomic. */ static DECLARE_BITMAP(need_init, MAX_SWAPFILES); -static bool backend_registered __read_mostly; /* * Register operations for frontswap, returning previous thus allowing * detection of multiple backends and possible nesting. */ -struct frontswap_ops frontswap_register_ops(struct frontswap_ops *ops) +struct frontswap_ops *frontswap_register_ops(struct frontswap_ops *ops) { - struct frontswap_ops old = frontswap_ops; + struct frontswap_ops *old = frontswap_ops; int i; - frontswap_ops = *ops; frontswap_enabled = true; for (i = 0; i < MAX_SWAPFILES; i++) { if (test_and_clear_bit(i, need_init)) - (*frontswap_ops.init)(i); + ops->init(i); } /* - * We MUST have backend_registered set _after_ the frontswap_init's + * We MUST have frontswap_ops set _after_ the frontswap_init's * have been called. Otherwise __frontswap_store might fail. Hence * the barrier to make sure compiler does not re-order us. */ barrier(); - backend_registered = true; + frontswap_ops = ops; return old; } EXPORT_SYMBOL(frontswap_register_ops); @@ -172,11 +170,11 @@ void __frontswap_init(unsigned type) { struct swap_info_struct *sis = swap_info[type]; - if (backend_registered) { + if (frontswap_ops) { BUG_ON(sis == NULL); if (sis->frontswap_map == NULL) return; - (*frontswap_ops.init)(type); + frontswap_ops->init(type); } else { BUG_ON(type > MAX_SWAPFILES); set_bit(type, need_init); @@ -206,7 +204,7 @@ int __frontswap_store(struct page *page) struct swap_info_struct *sis = swap_info[type]; pgoff_t offset = swp_offset(entry); - if (!backend_registered) { + if (!frontswap_ops) { inc_frontswap_failed_stores(); return ret; } @@ -215,7 +213,7 @@ int __frontswap_store(struct page *page) BUG_ON(sis == NULL); if (frontswap_test(sis, offset)) dup = 1; - ret = frontswap_ops.store(type, offset, page); + ret = frontswap_ops->store(type, offset, page); if (ret == 0) { frontswap_set(sis, offset); inc_frontswap_succ_stores(); @@ -250,13 +248,13 @@ int __frontswap_load(struct page *page) struct swap_info_struct *sis = swap_info[type]; pgoff_t offset = swp_offset(entry); - if (!backend_registered) + if (!frontswap_ops) return ret; BUG_ON(!PageLocked(page)); BUG_ON(sis == NULL); if (frontswap_test(sis, offset)) - ret = frontswap_ops.load(type, offset, page); + ret = frontswap_ops->load(type, offset, page); if (ret == 0) { inc_frontswap_loads(); if (frontswap_tmem_exclusive_gets_enabled) { @@ -276,12 +274,12 @@ void __frontswap_invalidate_page(unsigned type, pgoff_t offset) { struct swap_info_struct *sis = swap_info[type]; - if (!backend_registered) + if (!frontswap_ops) return; BUG_ON(sis == NULL); if (frontswap_test(sis, offset)) { - frontswap_ops.invalidate_page(type, offset); + frontswap_ops->invalidate_page(type, offset); __frontswap_clear(sis, offset); inc_frontswap_invalidates(); } @@ -296,11 +294,11 @@ void __frontswap_invalidate_area(unsigned type) { struct swap_info_struct *sis = swap_info[type]; - if (backend_registered) { + if (frontswap_ops) { BUG_ON(sis == NULL); if (sis->frontswap_map == NULL) return; - (*frontswap_ops.invalidate_area)(type); + frontswap_ops->invalidate_area(type); atomic_set(&sis->frontswap_pages, 0); memset(sis->frontswap_map, 0, sis->max / sizeof(long)); } -- cgit v1.2.3-70-g09d2 From 833f8662af9659508afc3cb80f09138eade378e2 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 30 Apr 2013 15:26:57 -0700 Subject: cleancache: Make cleancache_init use a pointer for the ops Instead of using a backend_registered to determine whether a backend is enabled. This allows us to remove the backend_register check and just do 'if (cleancache_ops)' [v1: Rebase on top of b97c4b430b0a (ramster->zcache move] Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Bob Liu Cc: Wanpeng Li Cc: Andor Daam Cc: Dan Magenheimer Cc: Florian Schmaus Cc: Minchan Kim Cc: Stefan Hengelein Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/zcache/zcache-main.c | 8 ++--- drivers/xen/tmem.c | 6 ++-- include/linux/cleancache.h | 2 +- mm/cleancache.c | 62 +++++++++++++++++++----------------- 4 files changed, 40 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 09c69c8026f9..6bd4ebb3494d 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1576,9 +1576,9 @@ static struct cleancache_ops zcache_cleancache_ops = { .init_fs = zcache_cleancache_init_fs }; -struct cleancache_ops zcache_cleancache_register_ops(void) +struct cleancache_ops *zcache_cleancache_register_ops(void) { - struct cleancache_ops old_ops = + struct cleancache_ops *old_ops = cleancache_register_ops(&zcache_cleancache_ops); return old_ops; @@ -1860,7 +1860,7 @@ static int __init zcache_init(void) } zbud_init(); if (zcache_enabled && !disable_cleancache) { - struct cleancache_ops old_ops; + struct cleancache_ops *old_ops; register_shrinker(&zcache_shrinker); old_ops = zcache_cleancache_register_ops(); @@ -1870,7 +1870,7 @@ static int __init zcache_init(void) pr_info("%s: cleancache: ignorenonactive = %d\n", namestr, !disable_cleancache_ignore_nonactive); #endif - if (old_ops.init_fs != NULL) + if (old_ops != NULL) pr_warn("%s: cleancache_ops overridden\n", namestr); } if (zcache_enabled && !disable_frontswap) { diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index 7a01a5fd0f63..fd79eab08368 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c @@ -236,7 +236,7 @@ static int __init no_cleancache(char *s) } __setup("nocleancache", no_cleancache); -static struct cleancache_ops __initdata tmem_cleancache_ops = { +static struct cleancache_ops tmem_cleancache_ops = { .put_page = tmem_cleancache_put_page, .get_page = tmem_cleancache_get_page, .invalidate_page = tmem_cleancache_flush_page, @@ -392,9 +392,9 @@ static int __init xen_tmem_init(void) BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); if (tmem_enabled && use_cleancache) { char *s = ""; - struct cleancache_ops old_ops = + struct cleancache_ops *old_ops = cleancache_register_ops(&tmem_cleancache_ops); - if (old_ops.init_fs != NULL) + if (old_ops) s = " (WARNING: cleancache_ops overridden)"; printk(KERN_INFO "cleancache enabled, RAM provided by " "Xen Transcendent Memory%s\n", s); diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h index 42e55deee757..3af5ea839558 100644 --- a/include/linux/cleancache.h +++ b/include/linux/cleancache.h @@ -33,7 +33,7 @@ struct cleancache_ops { void (*invalidate_fs)(int); }; -extern struct cleancache_ops +extern struct cleancache_ops * cleancache_register_ops(struct cleancache_ops *ops); extern void __cleancache_init_fs(struct super_block *); extern void __cleancache_init_shared_fs(char *, struct super_block *); diff --git a/mm/cleancache.c b/mm/cleancache.c index 0cecdbba4bcd..b3ae19b72035 100644 --- a/mm/cleancache.c +++ b/mm/cleancache.c @@ -32,7 +32,7 @@ EXPORT_SYMBOL(cleancache_enabled); * cleancache_ops is set by cleancache_ops_register to contain the pointers * to the cleancache "backend" implementation functions. */ -static struct cleancache_ops cleancache_ops __read_mostly; +static struct cleancache_ops *cleancache_ops __read_mostly; /* * Counters available via /sys/kernel/debug/frontswap (if debugfs is @@ -72,15 +72,14 @@ static DEFINE_MUTEX(poolid_mutex); /* * When set to false (default) all calls to the cleancache functions, except * the __cleancache_invalidate_fs and __cleancache_init_[shared|]fs are guarded - * by the if (!backend_registered) return. This means multiple threads (from - * different filesystems) will be checking backend_registered. The usage of a + * by the if (!cleancache_ops) return. This means multiple threads (from + * different filesystems) will be checking cleancache_ops. The usage of a * bool instead of a atomic_t or a bool guarded by a spinlock is OK - we are * OK if the time between the backend's have been initialized (and - * backend_registered has been set to true) and when the filesystems start + * cleancache_ops has been set to not NULL) and when the filesystems start * actually calling the backends. The inverse (when unloading) is obviously * not good - but this shim does not do that (yet). */ -static bool backend_registered __read_mostly; /* * The backends and filesystems work all asynchronously. This is b/c the @@ -90,13 +89,13 @@ static bool backend_registered __read_mostly; * [shared_|]fs_poolid_map and uuids for. * * b). user does I/Os -> we call the rest of __cleancache_* functions - * which return immediately as backend_registered is false. + * which return immediately as cleancache_ops is false. * * c). modprobe zcache -> cleancache_register_ops. We init the backend - * and set backend_registered to true, and for any fs_poolid_map + * and set cleancache_ops to true, and for any fs_poolid_map * (which is set by __cleancache_init_fs) we initialize the poolid. * - * d). user does I/Os -> now that backend_registered is true all the + * d). user does I/Os -> now that cleancache_ops is true all the * __cleancache_* functions can call the backend. They all check * that fs_poolid_map is valid and if so invoke the backend. * @@ -120,23 +119,26 @@ static bool backend_registered __read_mostly; * Register operations for cleancache, returning previous thus allowing * detection of multiple backends and possible nesting. */ -struct cleancache_ops cleancache_register_ops(struct cleancache_ops *ops) +struct cleancache_ops *cleancache_register_ops(struct cleancache_ops *ops) { - struct cleancache_ops old = cleancache_ops; + struct cleancache_ops *old = cleancache_ops; int i; mutex_lock(&poolid_mutex); - cleancache_ops = *ops; - - backend_registered = true; for (i = 0; i < MAX_INITIALIZABLE_FS; i++) { if (fs_poolid_map[i] == FS_NO_BACKEND) - fs_poolid_map[i] = (*cleancache_ops.init_fs)(PAGE_SIZE); + fs_poolid_map[i] = ops->init_fs(PAGE_SIZE); if (shared_fs_poolid_map[i] == FS_NO_BACKEND) - shared_fs_poolid_map[i] = (*cleancache_ops.init_shared_fs) + shared_fs_poolid_map[i] = ops->init_shared_fs (uuids[i], PAGE_SIZE); } -out: + /* + * We MUST set cleancache_ops _after_ we have called the backends + * init_fs or init_shared_fs functions. Otherwise the compiler might + * re-order where cleancache_ops is set in this function. + */ + barrier(); + cleancache_ops = ops; mutex_unlock(&poolid_mutex); return old; } @@ -151,8 +153,8 @@ void __cleancache_init_fs(struct super_block *sb) for (i = 0; i < MAX_INITIALIZABLE_FS; i++) { if (fs_poolid_map[i] == FS_UNKNOWN) { sb->cleancache_poolid = i + FAKE_FS_POOLID_OFFSET; - if (backend_registered) - fs_poolid_map[i] = (*cleancache_ops.init_fs)(PAGE_SIZE); + if (cleancache_ops) + fs_poolid_map[i] = cleancache_ops->init_fs(PAGE_SIZE); else fs_poolid_map[i] = FS_NO_BACKEND; break; @@ -172,8 +174,8 @@ void __cleancache_init_shared_fs(char *uuid, struct super_block *sb) if (shared_fs_poolid_map[i] == FS_UNKNOWN) { sb->cleancache_poolid = i + FAKE_SHARED_FS_POOLID_OFFSET; uuids[i] = uuid; - if (backend_registered) - shared_fs_poolid_map[i] = (*cleancache_ops.init_shared_fs) + if (cleancache_ops) + shared_fs_poolid_map[i] = cleancache_ops->init_shared_fs (uuid, PAGE_SIZE); else shared_fs_poolid_map[i] = FS_NO_BACKEND; @@ -240,7 +242,7 @@ int __cleancache_get_page(struct page *page) int fake_pool_id; struct cleancache_filekey key = { .u.key = { 0 } }; - if (!backend_registered) { + if (!cleancache_ops) { cleancache_failed_gets++; goto out; } @@ -255,7 +257,7 @@ int __cleancache_get_page(struct page *page) goto out; if (pool_id >= 0) - ret = (*cleancache_ops.get_page)(pool_id, + ret = cleancache_ops->get_page(pool_id, key, page->index, page); if (ret == 0) cleancache_succ_gets++; @@ -282,7 +284,7 @@ void __cleancache_put_page(struct page *page) int fake_pool_id; struct cleancache_filekey key = { .u.key = { 0 } }; - if (!backend_registered) { + if (!cleancache_ops) { cleancache_puts++; return; } @@ -296,7 +298,7 @@ void __cleancache_put_page(struct page *page) if (pool_id >= 0 && cleancache_get_key(page->mapping->host, &key) >= 0) { - (*cleancache_ops.put_page)(pool_id, key, page->index, page); + cleancache_ops->put_page(pool_id, key, page->index, page); cleancache_puts++; } } @@ -318,7 +320,7 @@ void __cleancache_invalidate_page(struct address_space *mapping, int fake_pool_id = mapping->host->i_sb->cleancache_poolid; struct cleancache_filekey key = { .u.key = { 0 } }; - if (!backend_registered) + if (!cleancache_ops) return; if (fake_pool_id >= 0) { @@ -328,7 +330,7 @@ void __cleancache_invalidate_page(struct address_space *mapping, VM_BUG_ON(!PageLocked(page)); if (cleancache_get_key(mapping->host, &key) >= 0) { - (*cleancache_ops.invalidate_page)(pool_id, + cleancache_ops->invalidate_page(pool_id, key, page->index); cleancache_invalidates++; } @@ -351,7 +353,7 @@ void __cleancache_invalidate_inode(struct address_space *mapping) int fake_pool_id = mapping->host->i_sb->cleancache_poolid; struct cleancache_filekey key = { .u.key = { 0 } }; - if (!backend_registered) + if (!cleancache_ops) return; if (fake_pool_id < 0) @@ -360,7 +362,7 @@ void __cleancache_invalidate_inode(struct address_space *mapping) pool_id = get_poolid_from_fake(fake_pool_id); if (pool_id >= 0 && cleancache_get_key(mapping->host, &key) >= 0) - (*cleancache_ops.invalidate_inode)(pool_id, key); + cleancache_ops->invalidate_inode(pool_id, key); } EXPORT_SYMBOL(__cleancache_invalidate_inode); @@ -387,8 +389,8 @@ void __cleancache_invalidate_fs(struct super_block *sb) fs_poolid_map[index] = FS_UNKNOWN; } sb->cleancache_poolid = -1; - if (backend_registered) - (*cleancache_ops.invalidate_fs)(old_poolid); + if (cleancache_ops) + cleancache_ops->invalidate_fs(old_poolid); mutex_unlock(&poolid_mutex); } EXPORT_SYMBOL(__cleancache_invalidate_fs); -- cgit v1.2.3-70-g09d2 From 10a7a0771399a57a297fca9615450dbb3f88081a Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Tue, 30 Apr 2013 15:27:00 -0700 Subject: xen: tmem: enable Xen tmem shim to be built/loaded as a module Allow Xen tmem shim to be built/loaded as a module. Xen self-ballooning and frontswap-selfshrinking are now also "lazily" initialized when the Xen tmem shim is loaded as a module, unless explicitly disabled by module parameters. Note runtime dependency disallows loading if cleancache/frontswap lazy initialization patches are not present. If built-in (not built as a module), the original mechanism of enabling via a kernel boot parameter is retained, but this should be considered deprecated. Note that module unload is explicitly not yet supported. [v1: Removed the [CLEANCACHE|FRONTSWAP]_HAS_LAZY_INIT ifdef] [v2: Squashed the xen/tmem: Remove the subsys call patch in] [akpm@linux-foundation.org: fix build (disable_frontswap_selfshrinking undeclared)] Signed-off-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Bob Liu Cc: Wanpeng Li Cc: Andor Daam Cc: Florian Schmaus Cc: Minchan Kim Cc: Stefan Hengelein Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/xen/Kconfig | 4 ++-- drivers/xen/tmem.c | 40 +++++++++++++++++++++++++++++++--------- drivers/xen/xen-selfballoon.c | 13 +++++-------- include/xen/tmem.h | 8 ++++++++ 4 files changed, 46 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 67af155cf602..dd4d9cb86243 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -145,9 +145,9 @@ config SWIOTLB_XEN select SWIOTLB config XEN_TMEM - bool + tristate depends on !ARM - default y if (CLEANCACHE || FRONTSWAP) + default m if (CLEANCACHE || FRONTSWAP) help Shim to interface in-kernel Transcendent Memory hooks (e.g. cleancache and frontswap) to Xen tmem hypercalls. diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index fd79eab08368..8adde8e8428c 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c @@ -5,6 +5,7 @@ * Author: Dan Magenheimer */ +#include #include #include #include @@ -128,6 +129,7 @@ static int xen_tmem_flush_object(u32 pool_id, struct tmem_oid oid) return xen_tmem_op(TMEM_FLUSH_OBJECT, pool_id, oid, 0, 0, 0, 0, 0); } +#ifndef CONFIG_XEN_TMEM_MODULE bool __read_mostly tmem_enabled = false; static int __init enable_tmem(char *s) @@ -136,6 +138,7 @@ static int __init enable_tmem(char *s) return 1; } __setup("tmem", enable_tmem); +#endif #ifdef CONFIG_CLEANCACHE static int xen_tmem_destroy_pool(u32 pool_id) @@ -227,14 +230,19 @@ static int tmem_cleancache_init_shared_fs(char *uuid, size_t pagesize) return xen_tmem_new_pool(shared_uuid, TMEM_POOL_SHARED, pagesize); } -static bool __initdata use_cleancache = true; - +static bool disable_cleancache __read_mostly; +static bool disable_selfballooning __read_mostly; +#ifdef CONFIG_XEN_TMEM_MODULE +module_param(disable_cleancache, bool, S_IRUGO); +module_param(disable_selfballooning, bool, S_IRUGO); +#else static int __init no_cleancache(char *s) { - use_cleancache = false; + disable_cleancache = true; return 1; } __setup("nocleancache", no_cleancache); +#endif static struct cleancache_ops tmem_cleancache_ops = { .put_page = tmem_cleancache_put_page, @@ -353,14 +361,19 @@ static void tmem_frontswap_init(unsigned ignored) xen_tmem_new_pool(private, TMEM_POOL_PERSIST, PAGE_SIZE); } -static bool __initdata use_frontswap = true; - +static bool disable_frontswap __read_mostly; +static bool disable_frontswap_selfshrinking __read_mostly; +#ifdef CONFIG_XEN_TMEM_MODULE +module_param(disable_frontswap, bool, S_IRUGO); +module_param(disable_frontswap_selfshrinking, bool, S_IRUGO); +#else static int __init no_frontswap(char *s) { - use_frontswap = false; + disable_frontswap = true; return 1; } __setup("nofrontswap", no_frontswap); +#endif static struct frontswap_ops tmem_frontswap_ops = { .store = tmem_frontswap_store, @@ -369,14 +382,16 @@ static struct frontswap_ops tmem_frontswap_ops = { .invalidate_area = tmem_frontswap_flush_area, .init = tmem_frontswap_init }; +#else /* CONFIG_FRONTSWAP */ +#define disable_frontswap_selfshrinking 1 #endif -static int __init xen_tmem_init(void) +static int xen_tmem_init(void) { if (!xen_domain()) return 0; #ifdef CONFIG_FRONTSWAP - if (tmem_enabled && use_frontswap) { + if (tmem_enabled && !disable_frontswap) { char *s = ""; struct frontswap_ops *old_ops = frontswap_register_ops(&tmem_frontswap_ops); @@ -390,7 +405,7 @@ static int __init xen_tmem_init(void) #endif #ifdef CONFIG_CLEANCACHE BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); - if (tmem_enabled && use_cleancache) { + if (tmem_enabled && !disable_cleancache) { char *s = ""; struct cleancache_ops *old_ops = cleancache_register_ops(&tmem_cleancache_ops); @@ -399,8 +414,15 @@ static int __init xen_tmem_init(void) printk(KERN_INFO "cleancache enabled, RAM provided by " "Xen Transcendent Memory%s\n", s); } +#endif +#ifdef CONFIG_XEN_SELFBALLOONING + xen_selfballoon_init(!disable_selfballooning, + !disable_frontswap_selfshrinking); #endif return 0; } module_init(xen_tmem_init) +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Dan Magenheimer "); +MODULE_DESCRIPTION("Shim to Xen transcendent memory"); diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c index 2552d3e0a70f..f2ef569c7cc1 100644 --- a/drivers/xen/xen-selfballoon.c +++ b/drivers/xen/xen-selfballoon.c @@ -121,7 +121,7 @@ static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process); static bool frontswap_selfshrinking __read_mostly; /* Enable/disable with kernel boot option. */ -static bool use_frontswap_selfshrink __initdata = true; +static bool use_frontswap_selfshrink = true; /* * The default values for the following parameters were deemed reasonable @@ -185,7 +185,7 @@ static int __init xen_nofrontswap_selfshrink_setup(char *s) __setup("noselfshrink", xen_nofrontswap_selfshrink_setup); /* Disable with kernel boot option. */ -static bool use_selfballooning __initdata = true; +static bool use_selfballooning = true; static int __init xen_noselfballooning_setup(char *s) { @@ -196,7 +196,7 @@ static int __init xen_noselfballooning_setup(char *s) __setup("noselfballooning", xen_noselfballooning_setup); #else /* !CONFIG_FRONTSWAP */ /* Enable with kernel boot option. */ -static bool use_selfballooning __initdata = false; +static bool use_selfballooning; static int __init xen_selfballooning_setup(char *s) { @@ -537,7 +537,7 @@ int register_xen_selfballooning(struct device *dev) } EXPORT_SYMBOL(register_xen_selfballooning); -static int __init xen_selfballoon_init(void) +int xen_selfballoon_init(bool use_selfballooning, bool use_frontswap_selfshrink) { bool enable = false; @@ -571,7 +571,4 @@ static int __init xen_selfballoon_init(void) return 0; } - -subsys_initcall(xen_selfballoon_init); - -MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(xen_selfballoon_init); diff --git a/include/xen/tmem.h b/include/xen/tmem.h index 591550a22ac7..3930a90045ff 100644 --- a/include/xen/tmem.h +++ b/include/xen/tmem.h @@ -3,7 +3,15 @@ #include +#ifdef CONFIG_XEN_TMEM_MODULE +#define tmem_enabled true +#else /* defined in drivers/xen/tmem.c */ extern bool tmem_enabled; +#endif + +#ifdef CONFIG_XEN_SELFBALLOONING +extern int xen_selfballoon_init(bool, bool); +#endif #endif /* _XEN_TMEM_H */ -- cgit v1.2.3-70-g09d2 From f42158fe6785dd366073c7fd00f159a65c631597 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 30 Apr 2013 15:27:01 -0700 Subject: zcache/tmem: Better error checking on frontswap_register_ops return value. In the past it either used to be NULL or the "older" backend. Now we also return -Exx error codes. Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Bob Liu Cc: Wanpeng Li Cc: Andor Daam Cc: Dan Magenheimer Cc: Florian Schmaus Cc: Minchan Kim Cc: Stefan Hengelein Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/zcache/zcache-main.c | 5 ++++- drivers/xen/tmem.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 6bd4ebb3494d..118602ff3aed 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1886,8 +1886,11 @@ static int __init zcache_init(void) namestr, frontswap_has_exclusive_gets, !disable_frontswap_ignore_nonactive); #endif - if (old_ops != NULL) + if (IS_ERR(old_ops) || old_ops) { + if (IS_ERR(old_ops)) + return PTR_RET(old_ops); pr_warn("%s: frontswap_ops overridden\n", namestr); + } } if (ramster_enabled) ramster_init(!disable_cleancache, !disable_frontswap, diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index 8adde8e8428c..e3600be4e7fa 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c @@ -397,8 +397,11 @@ static int xen_tmem_init(void) frontswap_register_ops(&tmem_frontswap_ops); tmem_frontswap_poolid = -1; - if (old_ops) + if (IS_ERR(old_ops) || old_ops) { + if (IS_ERR(old_ops)) + return PTR_ERR(old_ops); s = " (WARNING: frontswap_ops overridden)"; + } printk(KERN_INFO "frontswap enabled, RAM provided by " "Xen Transcendent Memory%s\n", s); } -- cgit v1.2.3-70-g09d2 From 1ac37bee81531cb62a9a64e78ffdad7da9b20ea2 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Tue, 30 Apr 2013 15:27:03 -0700 Subject: staging: zcache: enable ramster to be built/loaded as a module Enable module support for ramster. Note runtime dependency disallows loading if cleancache/frontswap lazy initialization patches are not present. If built-in (not built as a module), the original mechanism of enabling via a kernel boot parameter is retained, but this should be considered deprecated. Note that module unload is explicitly not yet supported. [v1: Fixed compile issues since ramster_init now has four arguments] [v2: Fixed rebase on ramster->zcache move] [akpm@linux-foundation.org: use_frontswap_selfshrink cannot be __initdata] Signed-off-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Bob Liu Cc: Wanpeng Li Cc: Andor Daam Cc: Florian Schmaus Cc: Minchan Kim Cc: Stefan Hengelein Cc: Wu Fengguang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/zcache/ramster.h | 6 ++++- drivers/staging/zcache/ramster/debug.c | 2 +- drivers/staging/zcache/ramster/nodemanager.c | 9 ++++--- drivers/staging/zcache/ramster/ramster.c | 29 ++++++++++++++++++---- drivers/staging/zcache/ramster/ramster.h | 2 +- .../staging/zcache/ramster/ramster_nodemanager.h | 2 ++ drivers/staging/zcache/zcache-main.c | 2 +- 7 files changed, 39 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/ramster.h b/drivers/staging/zcache/ramster.h index 1b71aea2ff62..e1f91d5a0f6a 100644 --- a/drivers/staging/zcache/ramster.h +++ b/drivers/staging/zcache/ramster.h @@ -11,10 +11,14 @@ #ifndef _ZCACHE_RAMSTER_H_ #define _ZCACHE_RAMSTER_H_ +#ifdef CONFIG_RAMSTER_MODULE +#define CONFIG_RAMSTER +#endif + #ifdef CONFIG_RAMSTER #include "ramster/ramster.h" #else -static inline void ramster_init(bool x, bool y, bool z) +static inline void ramster_init(bool x, bool y, bool z, bool w) { } diff --git a/drivers/staging/zcache/ramster/debug.c b/drivers/staging/zcache/ramster/debug.c index bf34133cc631..327e4f0d98e1 100644 --- a/drivers/staging/zcache/ramster/debug.c +++ b/drivers/staging/zcache/ramster/debug.c @@ -43,7 +43,7 @@ static struct debug_entry { }; #undef ATTR -int __init ramster_debugfs_init(void) +int ramster_debugfs_init(void) { int i; struct dentry *root = debugfs_create_dir("ramster", NULL); diff --git a/drivers/staging/zcache/ramster/nodemanager.c b/drivers/staging/zcache/ramster/nodemanager.c index c0f48158735d..2cfe93342c0d 100644 --- a/drivers/staging/zcache/ramster/nodemanager.c +++ b/drivers/staging/zcache/ramster/nodemanager.c @@ -949,7 +949,7 @@ static void __exit exit_r2nm(void) r2hb_exit(); } -static int __init init_r2nm(void) +int r2nm_init(void) { int ret = -1; @@ -986,10 +986,11 @@ out_r2hb: out: return ret; } +EXPORT_SYMBOL_GPL(r2nm_init); MODULE_AUTHOR("Oracle"); MODULE_LICENSE("GPL"); -/* module_init(init_r2nm) */ -late_initcall(init_r2nm); -/* module_exit(exit_r2nm) */ +#ifndef CONFIG_RAMSTER_MODULE +late_initcall(r2nm_init); +#endif diff --git a/drivers/staging/zcache/ramster/ramster.c b/drivers/staging/zcache/ramster/ramster.c index 87816279ce3c..b18b887db79f 100644 --- a/drivers/staging/zcache/ramster/ramster.c +++ b/drivers/staging/zcache/ramster/ramster.c @@ -121,6 +121,7 @@ int ramster_do_preload_flnode(struct tmem_pool *pool) kmem_cache_free(ramster_flnode_cache, flnode); return ret; } +EXPORT_SYMBOL_GPL(ramster_do_preload_flnode); /* * Called by the message handler after a (still compressed) page has been @@ -388,6 +389,7 @@ void *ramster_pampd_free(void *pampd, struct tmem_pool *pool, } return local_pampd; } +EXPORT_SYMBOL_GPL(ramster_pampd_free); void ramster_count_foreign_pages(bool eph, int count) { @@ -408,6 +410,7 @@ void ramster_count_foreign_pages(bool eph, int count) } } } +EXPORT_SYMBOL_GPL(ramster_count_foreign_pages); /* * For now, just push over a few pages every few seconds to @@ -593,7 +596,7 @@ requeue: ramster_remotify_queue_delayed_work(HZ); } -void __init ramster_remotify_init(void) +void ramster_remotify_init(void) { unsigned long n = 60UL; ramster_remotify_workqueue = @@ -768,8 +771,10 @@ static bool frontswap_selfshrinking __read_mostly; static void selfshrink_process(struct work_struct *work); static DECLARE_DELAYED_WORK(selfshrink_worker, selfshrink_process); +#ifndef CONFIG_RAMSTER_MODULE /* Enable/disable with kernel boot option. */ -static bool use_frontswap_selfshrink __initdata = true; +static bool use_frontswap_selfshrink = true; +#endif /* * The default values for the following parameters were deemed reasonable @@ -824,6 +829,7 @@ static void frontswap_selfshrink(void) frontswap_shrink(tgt_frontswap_pages); } +#ifndef CONFIG_RAMSTER_MODULE static int __init ramster_nofrontswap_selfshrink_setup(char *s) { use_frontswap_selfshrink = false; @@ -831,6 +837,7 @@ static int __init ramster_nofrontswap_selfshrink_setup(char *s) } __setup("noselfshrink", ramster_nofrontswap_selfshrink_setup); +#endif static void selfshrink_process(struct work_struct *work) { @@ -849,6 +856,7 @@ void ramster_cpu_up(int cpu) per_cpu(ramster_remoteputmem1, cpu) = p1; per_cpu(ramster_remoteputmem2, cpu) = p2; } +EXPORT_SYMBOL_GPL(ramster_cpu_up); void ramster_cpu_down(int cpu) { @@ -864,6 +872,7 @@ void ramster_cpu_down(int cpu) kp->flnode = NULL; } } +EXPORT_SYMBOL_GPL(ramster_cpu_down); void ramster_register_pamops(struct tmem_pamops *pamops) { @@ -874,9 +883,11 @@ void ramster_register_pamops(struct tmem_pamops *pamops) pamops->repatriate = ramster_pampd_repatriate; pamops->repatriate_preload = ramster_pampd_repatriate_preload; } +EXPORT_SYMBOL_GPL(ramster_register_pamops); -void __init ramster_init(bool cleancache, bool frontswap, - bool frontswap_exclusive_gets) +void ramster_init(bool cleancache, bool frontswap, + bool frontswap_exclusive_gets, + bool frontswap_selfshrink) { int ret = 0; @@ -891,10 +902,17 @@ void __init ramster_init(bool cleancache, bool frontswap, if (ret) pr_err("ramster: can't create sysfs for ramster\n"); (void)r2net_register_handlers(); +#ifdef CONFIG_RAMSTER_MODULE + ret = r2nm_init(); + if (ret) + pr_err("ramster: can't init r2net\n"); + frontswap_selfshrinking = frontswap_selfshrink; +#else + frontswap_selfshrinking = use_frontswap_selfshrink; +#endif INIT_LIST_HEAD(&ramster_rem_op_list); ramster_flnode_cache = kmem_cache_create("ramster_flnode", sizeof(struct flushlist_node), 0, 0, NULL); - frontswap_selfshrinking = use_frontswap_selfshrink; if (frontswap_selfshrinking) { pr_info("ramster: Initializing frontswap selfshrink driver.\n"); schedule_delayed_work(&selfshrink_worker, @@ -902,3 +920,4 @@ void __init ramster_init(bool cleancache, bool frontswap, } ramster_remotify_init(); } +EXPORT_SYMBOL_GPL(ramster_init); diff --git a/drivers/staging/zcache/ramster/ramster.h b/drivers/staging/zcache/ramster/ramster.h index 12ae56f09ca4..6d41a7a772e3 100644 --- a/drivers/staging/zcache/ramster/ramster.h +++ b/drivers/staging/zcache/ramster/ramster.h @@ -147,7 +147,7 @@ extern int r2net_register_handlers(void); extern int r2net_remote_target_node_set(int); extern int ramster_remotify_pageframe(bool); -extern void ramster_init(bool, bool, bool); +extern void ramster_init(bool, bool, bool, bool); extern void ramster_register_pamops(struct tmem_pamops *); extern int ramster_localify(int, struct tmem_oid *oidp, uint32_t, char *, unsigned int, void *); diff --git a/drivers/staging/zcache/ramster/ramster_nodemanager.h b/drivers/staging/zcache/ramster/ramster_nodemanager.h index 49f879d943ab..dbaae34ea613 100644 --- a/drivers/staging/zcache/ramster/ramster_nodemanager.h +++ b/drivers/staging/zcache/ramster/ramster_nodemanager.h @@ -36,4 +36,6 @@ /* host name, group name, cluster name all 64 bytes */ #define R2NM_MAX_NAME_LEN 64 /* __NEW_UTS_LEN */ +extern int r2nm_init(void); + #endif /* _RAMSTER_NODEMANAGER_H */ diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 118602ff3aed..326c2ea17c38 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1894,7 +1894,7 @@ static int __init zcache_init(void) } if (ramster_enabled) ramster_init(!disable_cleancache, !disable_frontswap, - frontswap_has_exclusive_gets); + frontswap_has_exclusive_gets, false); out: return ret; } -- cgit v1.2.3-70-g09d2 From 835f2f51608fd80e1aef5a8955dabcc36ea528a4 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Tue, 30 Apr 2013 15:27:05 -0700 Subject: staging: zcache: enable zcache to be built/loaded as a module Allow zcache to be built/loaded as a module. Note runtime dependency disallows loading if cleancache/frontswap lazy initialization patches are not present. Zsmalloc support has not yet been merged into zcache but, once merged, could now easily be selected via a module_param. If built-in (not built as a module), the original mechanism of enabling via a kernel boot parameter is retained, but this should be considered deprecated. Note that module unload is explicitly not yet supported. Signed-off-by: Dan Magenheimer [v1: Rebased with different order of patches] [v2: Removed [CLEANCACHE|FRONTSWAP]_HAS_LAZY_INIT ifdef] [v3: Rebased on top of ramster->zcache move] [v4: Redid the Makefile] [v5: s/ZCACHE2/ZCACHE/] Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Bob Liu Cc: Wanpeng Li Cc: Andor Daam Cc: Florian Schmaus Cc: Minchan Kim Cc: Stefan Hengelein Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/zcache/Kconfig | 6 ++--- drivers/staging/zcache/tmem.c | 6 ++++- drivers/staging/zcache/tmem.h | 8 +++---- drivers/staging/zcache/zcache-main.c | 45 +++++++++++++++++++++++++++++++++--- drivers/staging/zcache/zcache.h | 2 +- 5 files changed, 55 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 05e87a1e5d93..2d7b2da3b9e0 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -1,5 +1,5 @@ config ZCACHE - bool "Dynamic compression of swap pages and clean pagecache pages" + tristate "Dynamic compression of swap pages and clean pagecache pages" depends on CRYPTO=y && SWAP=y && CLEANCACHE && FRONTSWAP select CRYPTO_LZO default n @@ -19,8 +19,8 @@ config ZCACHE_DEBUG how zcache is doing. You probably want to set this to 'N'. config RAMSTER - bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE=y + tristate "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" + depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE depends on NET # must ensure struct page is 8-byte aligned select HAVE_ALIGNED_STRUCT_PAGE if !64BIT diff --git a/drivers/staging/zcache/tmem.c b/drivers/staging/zcache/tmem.c index a2b7e03b6062..d7e51e4152eb 100644 --- a/drivers/staging/zcache/tmem.c +++ b/drivers/staging/zcache/tmem.c @@ -35,7 +35,8 @@ #include #include #include -#ifdef CONFIG_RAMSTER +#include +#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) #include #endif @@ -641,6 +642,7 @@ void *tmem_localify_get_pampd(struct tmem_pool *pool, struct tmem_oid *oidp, /* note, hashbucket remains locked */ return pampd; } +EXPORT_SYMBOL_GPL(tmem_localify_get_pampd); void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, void *pampd, void *saved_hb, bool delete) @@ -658,6 +660,7 @@ void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, } spin_unlock(&hb->lock); } +EXPORT_SYMBOL_GPL(tmem_localify_finish); /* * For ramster only. Helper function to support asynchronous tmem_get. @@ -719,6 +722,7 @@ out: spin_unlock(&hb->lock); return ret; } +EXPORT_SYMBOL_GPL(tmem_replace); #endif /* diff --git a/drivers/staging/zcache/tmem.h b/drivers/staging/zcache/tmem.h index adbe5a8f28aa..d128ce290f1f 100644 --- a/drivers/staging/zcache/tmem.h +++ b/drivers/staging/zcache/tmem.h @@ -126,7 +126,7 @@ static inline unsigned tmem_oid_hash(struct tmem_oid *oidp) TMEM_HASH_BUCKET_BITS); } -#ifdef CONFIG_RAMSTER +#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) struct tmem_xhandle { uint8_t client_id; uint8_t xh_data_cksum; @@ -171,7 +171,7 @@ struct tmem_obj { unsigned int objnode_tree_height; unsigned long objnode_count; long pampd_count; -#ifdef CONFIG_RAMSTER +#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) /* * for current design of ramster, all pages belonging to * an object reside on the same remotenode and extra is @@ -215,7 +215,7 @@ struct tmem_pamops { uint32_t); void (*free)(void *, struct tmem_pool *, struct tmem_oid *, uint32_t, bool); -#ifdef CONFIG_RAMSTER +#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) void (*new_obj)(struct tmem_obj *); void (*free_obj)(struct tmem_pool *, struct tmem_obj *, bool); void *(*repatriate_preload)(void *, struct tmem_pool *, @@ -247,7 +247,7 @@ extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); extern int tmem_destroy_pool(struct tmem_pool *); extern void tmem_new_pool(struct tmem_pool *, uint32_t); -#ifdef CONFIG_RAMSTER +#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, void *); extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *, diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 326c2ea17c38..522cb8e55142 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -37,8 +37,10 @@ #include "debug.h" #ifdef CONFIG_RAMSTER static bool ramster_enabled __read_mostly; +static int disable_frontswap_selfshrink; #else #define ramster_enabled false +#define disable_frontswap_selfshrink 0 #endif #ifndef __PG_WAS_ACTIVE @@ -81,8 +83,12 @@ static char *namestr __read_mostly = "zcache"; (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) /* crypto API for zcache */ +#ifdef CONFIG_ZCACHE_MODULE +static char *zcache_comp_name = "lzo"; +#else #define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME static char zcache_comp_name[ZCACHE_COMP_NAME_SZ] __read_mostly; +#endif static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms __read_mostly; enum comp_op { @@ -1721,6 +1727,7 @@ struct frontswap_ops *zcache_frontswap_register_ops(void) * OR NOTHING HAPPENS! */ +#ifndef CONFIG_ZCACHE_MODULE static int __init enable_zcache(char *s) { zcache_enabled = true; @@ -1787,18 +1794,27 @@ static int __init enable_zcache_compressor(char *s) return 1; } __setup("zcache=", enable_zcache_compressor); +#endif -static int __init zcache_comp_init(void) +static int zcache_comp_init(void) { int ret = 0; /* check crypto algorithm */ +#ifdef CONFIG_ZCACHE_MODULE + ret = crypto_has_comp(zcache_comp_name, 0, 0); + if (!ret) { + ret = -1; + goto out; + } +#else if (*zcache_comp_name != '\0') { ret = crypto_has_comp(zcache_comp_name, 0, 0); if (!ret) pr_info("zcache: %s not supported\n", zcache_comp_name); + goto out; } if (!ret) strcpy(zcache_comp_name, "lzo"); @@ -1807,6 +1823,7 @@ static int __init zcache_comp_init(void) ret = 1; goto out; } +#endif pr_info("zcache: using %s compressor\n", zcache_comp_name); /* alloc percpu transforms */ @@ -1818,10 +1835,13 @@ out: return ret; } -static int __init zcache_init(void) +static int zcache_init(void) { int ret = 0; +#ifdef CONFIG_ZCACHE_MODULE + zcache_enabled = 1; +#endif if (ramster_enabled) { namestr = "ramster"; ramster_register_pamops(&zcache_pamops); @@ -1894,9 +1914,28 @@ static int __init zcache_init(void) } if (ramster_enabled) ramster_init(!disable_cleancache, !disable_frontswap, - frontswap_has_exclusive_gets, false); + frontswap_has_exclusive_gets, + !disable_frontswap_selfshrink); out: return ret; } +#ifdef CONFIG_ZCACHE_MODULE +#ifdef CONFIG_RAMSTER +module_param(ramster_enabled, int, S_IRUGO); +module_param(disable_frontswap_selfshrink, int, S_IRUGO); +#endif +module_param(disable_cleancache, int, S_IRUGO); +module_param(disable_frontswap, int, S_IRUGO); +#ifdef FRONTSWAP_HAS_EXCLUSIVE_GETS +module_param(frontswap_has_exclusive_gets, bool, S_IRUGO); +#endif +module_param(disable_frontswap_ignore_nonactive, int, S_IRUGO); +module_param(zcache_comp_name, charp, S_IRUGO); +module_init(zcache_init); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Dan Magenheimer "); +MODULE_DESCRIPTION("In-kernel compression of cleancache/frontswap pages"); +#else late_initcall(zcache_init); +#endif diff --git a/drivers/staging/zcache/zcache.h b/drivers/staging/zcache/zcache.h index 81722b33b087..849120095e79 100644 --- a/drivers/staging/zcache/zcache.h +++ b/drivers/staging/zcache/zcache.h @@ -39,7 +39,7 @@ extern int zcache_flush_page(int, int, struct tmem_oid *, uint32_t); extern int zcache_flush_object(int, int, struct tmem_oid *); extern void zcache_decompress_to_page(char *, unsigned int, struct page *); -#ifdef CONFIG_RAMSTER +#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) extern void *zcache_pampd_create(char *, unsigned int, bool, int, struct tmem_handle *); int zcache_autocreate_pool(unsigned int cli_id, unsigned int pool_id, bool eph); -- cgit v1.2.3-70-g09d2 From c90fe6bc0343f7c26b30c9f503b1d061636ac8ee Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 30 Apr 2013 15:27:14 -0700 Subject: dmi: morph dmi_dump_ids() into dmi_format_ids() which formats into a buffer We're goning to use DMI identification for other purposes too. Morph dmi_dump_ids() which is used to print DMI identification as a debug message during boot into dmi_format_ids() which formats the same information sans the leading "DMI:" tag into a string buffer. dmi_present() is updated to format the information into dmi_ids_string[] using the new function and print it with "DMI:" prefix. dmi_ids_string[] will be used for another purpose by a future patch. Signed-off-by: Tejun Heo Cc: Bjorn Helgaas Cc: David S. Miller Cc: Fengguang Wu Cc: Heiko Carstens Cc: Jesper Nilsson Cc: Martin Schwidefsky Cc: Mike Frysinger Cc: Vineet Gupta Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/firmware/dmi_scan.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 4cd392dbf115..862b1d27a85b 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -22,6 +22,9 @@ static u16 __initdata dmi_ver; */ static int dmi_initialized; +/* DMI system identification string used during boot */ +static char dmi_ids_string[128] __initdata; + static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s) { const u8 *bp = ((u8 *) dm) + dm->length; @@ -376,38 +379,44 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy) } } -static void __init print_filtered(const char *info) +static int __init print_filtered(char *buf, size_t len, const char *info) { + int c = 0; const char *p; if (!info) - return; + return c; for (p = info; *p; p++) if (isprint(*p)) - printk(KERN_CONT "%c", *p); + c += scnprintf(buf + c, len - c, "%c", *p); else - printk(KERN_CONT "\\x%02x", *p & 0xff); + c += scnprintf(buf + c, len - c, "\\x%02x", *p & 0xff); + return c; } -static void __init dmi_dump_ids(void) +static void __init dmi_format_ids(char *buf, size_t len) { + int c = 0; const char *board; /* Board Name is optional */ - printk(KERN_DEBUG "DMI: "); - print_filtered(dmi_get_system_info(DMI_SYS_VENDOR)); - printk(KERN_CONT " "); - print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME)); + c += print_filtered(buf + c, len - c, + dmi_get_system_info(DMI_SYS_VENDOR)); + c += scnprintf(buf + c, len - c, " "); + c += print_filtered(buf + c, len - c, + dmi_get_system_info(DMI_PRODUCT_NAME)); + board = dmi_get_system_info(DMI_BOARD_NAME); if (board) { - printk(KERN_CONT "/"); - print_filtered(board); + c += scnprintf(buf + c, len - c, "/"); + c += print_filtered(buf + c, len - c, board); } - printk(KERN_CONT ", BIOS "); - print_filtered(dmi_get_system_info(DMI_BIOS_VERSION)); - printk(KERN_CONT " "); - print_filtered(dmi_get_system_info(DMI_BIOS_DATE)); - printk(KERN_CONT "\n"); + c += scnprintf(buf + c, len - c, ", BIOS "); + c += print_filtered(buf + c, len - c, + dmi_get_system_info(DMI_BIOS_VERSION)); + c += scnprintf(buf + c, len - c, " "); + c += print_filtered(buf + c, len - c, + dmi_get_system_info(DMI_BIOS_DATE)); } static int __init dmi_present(const char __iomem *p) @@ -431,7 +440,8 @@ static int __init dmi_present(const char __iomem *p) pr_info("Legacy DMI %d.%d present.\n", dmi_ver >> 8, dmi_ver & 0xFF); } - dmi_dump_ids(); + dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string)); + printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string); return 0; } } -- cgit v1.2.3-70-g09d2 From 98e5e1bf722c4f976a860aed06dd365a56a34ee0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 30 Apr 2013 15:27:15 -0700 Subject: dump_stack: implement arch-specific hardware description in task dumps x86 and ia64 can acquire extra hardware identification information from DMI and print it along with task dumps; however, the usage isn't consistent. * x86 show_regs() collects vendor, product and board strings and print them out with PID, comm and utsname. Some of the information is printed again later in the same dump. * warn_slowpath_common() explicitly accesses the DMI board and prints it out with "Hardware name:" label. This applies to both x86 and ia64 but is irrelevant on all other archs. * ia64 doesn't show DMI information on other non-WARN dumps. This patch introduces arch-specific hardware description used by dump_stack(). It can be set by calling dump_stack_set_arch_desc() during boot and, if exists, printed out in a separate line with "Hardware name:" label. dmi_set_dump_stack_arch_desc() is added which sets arch-specific description from DMI data. It uses dmi_ids_string[] which is set from dmi_present() used for DMI debug message. It is superset of the information x86 show_regs() is using. The function is called from x86 and ia64 boot code right after dmi_scan_machine(). This makes the explicit DMI handling in warn_slowpath_common() unnecessary. Removed. show_regs() isn't yet converted to use generic debug information printing and this patch doesn't remove the duplicate DMI handling in x86 show_regs(). The next patch will unify show_regs() handling and remove the duplication. An example WARN dump follows. WARNING: at kernel/workqueue.c:4841 init_workqueues+0x35/0x505() Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.9.0-rc1-work+ #3 Hardware name: empty empty/S3992, BIOS 080011 10/26/2007 0000000000000009 ffff88007c861e08 ffffffff81c614dc ffff88007c861e48 ffffffff8108f500 ffffffff82228240 0000000000000040 ffffffff8234a08e 0000000000000000 0000000000000000 0000000000000000 ffff88007c861e58 Call Trace: [] dump_stack+0x19/0x1b [] warn_slowpath_common+0x70/0xa0 [] warn_slowpath_null+0x1a/0x20 [] init_workqueues+0x35/0x505 ... v2: Use the same string as the debug message from dmi_present() which also contains BIOS information. Move hardware name into its own line as warn_slowpath_common() did. This change was suggested by Bjorn Helgaas. Signed-off-by: Tejun Heo Cc: Bjorn Helgaas Cc: David S. Miller Cc: Fengguang Wu Cc: Heiko Carstens Cc: Jesper Nilsson Cc: Martin Schwidefsky Cc: Mike Frysinger Cc: Vineet Gupta Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/setup.c | 1 + arch/x86/kernel/setup.c | 1 + drivers/firmware/dmi_scan.c | 13 +++++++++++++ include/linux/dmi.h | 2 ++ include/linux/printk.h | 5 +++++ kernel/panic.c | 6 ------ kernel/printk.c | 26 ++++++++++++++++++++++++++ 7 files changed, 48 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 2029cc0d2fc6..13bfdd22afc8 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -1063,6 +1063,7 @@ check_bugs (void) static int __init run_dmi_scan(void) { dmi_scan_machine(); + dmi_set_dump_stack_arch_desc(); return 0; } core_initcall(run_dmi_scan); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 4689855c2f8a..56f7fcfe7fa2 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -996,6 +996,7 @@ void __init setup_arch(char **cmdline_p) efi_init(); dmi_scan_machine(); + dmi_set_dump_stack_arch_desc(); /* * VMware detection requires dmi to be available, so this diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 862b1d27a85b..98c62081c034 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -530,6 +530,19 @@ void __init dmi_scan_machine(void) dmi_initialized = 1; } +/** + * dmi_set_dump_stack_arch_desc - set arch description for dump_stack() + * + * Invoke dump_stack_set_arch_desc() with DMI system information so that + * DMI identifiers are printed out on task dumps. Arch boot code should + * call this function after dmi_scan_machine() if it wants to print out DMI + * identifiers on task dumps. + */ +void __init dmi_set_dump_stack_arch_desc(void) +{ + dump_stack_set_arch_desc("%s", dmi_ids_string); +} + /** * dmi_matches - check if dmi_system_id structure matches system DMI data * @dmi: pointer to the dmi_system_id structure to check diff --git a/include/linux/dmi.h b/include/linux/dmi.h index f156cca25ad0..b6eb7a05d58e 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -99,6 +99,7 @@ extern const char * dmi_get_system_info(int field); extern const struct dmi_device * dmi_find_device(int type, const char *name, const struct dmi_device *from); extern void dmi_scan_machine(void); +extern void dmi_set_dump_stack_arch_desc(void); extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); extern int dmi_name_in_vendors(const char *str); extern int dmi_name_in_serial(const char *str); @@ -114,6 +115,7 @@ static inline const char * dmi_get_system_info(int field) { return NULL; } static inline const struct dmi_device * dmi_find_device(int type, const char *name, const struct dmi_device *from) { return NULL; } static inline void dmi_scan_machine(void) { return; } +static inline void dmi_set_dump_stack_arch_desc(void) { } static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) { if (yearp) diff --git a/include/linux/printk.h b/include/linux/printk.h index 7ce1f878cf6a..47827c0a034d 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -145,6 +145,7 @@ extern void wake_up_klogd(void); void log_buf_kexec_setup(void); void __init setup_log_buf(int early); +void dump_stack_set_arch_desc(const char *fmt, ...); void dump_stack_print_info(const char *log_lvl); #else static inline __printf(1, 0) @@ -184,6 +185,10 @@ static inline void setup_log_buf(int early) { } +static inline void dump_stack_set_arch_desc(const char *fmt, ...) +{ +} + static inline void dump_stack_print_info(const char *log_lvl) { } diff --git a/kernel/panic.c b/kernel/panic.c index 7c57cc9eee2c..167ec097ce8b 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -22,7 +22,6 @@ #include #include #include -#include #define PANIC_TIMER_STEP 100 #define PANIC_BLINK_SPD 18 @@ -400,13 +399,8 @@ struct slowpath_args { static void warn_slowpath_common(const char *file, int line, void *caller, unsigned taint, struct slowpath_args *args) { - const char *board; - printk(KERN_WARNING "------------[ cut here ]------------\n"); printk(KERN_WARNING "WARNING: at %s:%d %pS()\n", file, line, caller); - board = dmi_get_system_info(DMI_PRODUCT_NAME); - if (board) - printk(KERN_WARNING "Hardware name: %s\n", board); if (args) vprintk(args->fmt, args->args); diff --git a/kernel/printk.c b/kernel/printk.c index 70b4b94a0eca..73a96def4804 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -2851,6 +2851,28 @@ void kmsg_dump_rewind(struct kmsg_dumper *dumper) } EXPORT_SYMBOL_GPL(kmsg_dump_rewind); +static char dump_stack_arch_desc_str[128]; + +/** + * dump_stack_set_arch_desc - set arch-specific str to show with task dumps + * @fmt: printf-style format string + * @...: arguments for the format string + * + * The configured string will be printed right after utsname during task + * dumps. Usually used to add arch-specific system identifiers. If an + * arch wants to make use of such an ID string, it should initialize this + * as soon as possible during boot. + */ +void __init dump_stack_set_arch_desc(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsnprintf(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str), + fmt, args); + va_end(args); +} + /** * dump_stack_print_info - print generic debug info for dump_stack() * @log_lvl: log level @@ -2865,6 +2887,10 @@ void dump_stack_print_info(const char *log_lvl) print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), init_utsname()->version); + + if (dump_stack_arch_desc_str[0] != '\0') + printk("%sHardware name: %s\n", + log_lvl, dump_stack_arch_desc_str); } #endif -- cgit v1.2.3-70-g09d2 From 16c7fa05829e8b91db48e3539c5d6ff3c2b18a23 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 30 Apr 2013 15:27:30 -0700 Subject: lib/string_helpers: introduce generic string_unescape There are several places in kernel where modules unescapes input to convert C-Style Escape Sequences into byte codes. The patch provides generic implementation of such approach. Test cases are also included into the patch. [akpm@linux-foundation.org: clarify comment] [akpm@linux-foundation.org: export get_random_int() to modules] Signed-off-by: Andy Shevchenko Cc: Samuel Thibault Cc: Greg Kroah-Hartman Cc: Jason Baron Cc: Alexander Viro Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/random.c | 1 + include/linux/string_helpers.h | 58 ++++++++++++++++++ lib/Kconfig.debug | 3 + lib/Makefile | 4 +- lib/string_helpers.c | 133 +++++++++++++++++++++++++++++++++++++++++ lib/test-string_helpers.c | 103 +++++++++++++++++++++++++++++++ 6 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 lib/test-string_helpers.c (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 32a6c5764950..cd9a6211dcad 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1485,6 +1485,7 @@ unsigned int get_random_int(void) return ret; } +EXPORT_SYMBOL(get_random_int); /* * randomize_range() returns a start address such that diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h index a3eb2f65b656..3eeee9672a4a 100644 --- a/include/linux/string_helpers.h +++ b/include/linux/string_helpers.h @@ -13,4 +13,62 @@ enum string_size_units { int string_get_size(u64 size, enum string_size_units units, char *buf, int len); +#define UNESCAPE_SPACE 0x01 +#define UNESCAPE_OCTAL 0x02 +#define UNESCAPE_HEX 0x04 +#define UNESCAPE_SPECIAL 0x08 +#define UNESCAPE_ANY \ + (UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_HEX | UNESCAPE_SPECIAL) + +/** + * string_unescape - unquote characters in the given string + * @src: source buffer (escaped) + * @dst: destination buffer (unescaped) + * @size: size of the destination buffer (0 to unlimit) + * @flags: combination of the flags (bitwise OR): + * %UNESCAPE_SPACE: + * '\f' - form feed + * '\n' - new line + * '\r' - carriage return + * '\t' - horizontal tab + * '\v' - vertical tab + * %UNESCAPE_OCTAL: + * '\NNN' - byte with octal value NNN (1 to 3 digits) + * %UNESCAPE_HEX: + * '\xHH' - byte with hexadecimal value HH (1 to 2 digits) + * %UNESCAPE_SPECIAL: + * '\"' - double quote + * '\\' - backslash + * '\a' - alert (BEL) + * '\e' - escape + * %UNESCAPE_ANY: + * all previous together + * + * Returns amount of characters processed to the destination buffer excluding + * trailing '\0'. + * + * Because the size of the output will be the same as or less than the size of + * the input, the transformation may be performed in place. + * + * Caller must provide valid source and destination pointers. Be aware that + * destination buffer will always be NULL-terminated. Source string must be + * NULL-terminated as well. + */ +int string_unescape(char *src, char *dst, size_t size, unsigned int flags); + +static inline int string_unescape_inplace(char *buf, unsigned int flags) +{ + return string_unescape(buf, buf, 0, flags); +} + +static inline int string_unescape_any(char *src, char *dst, size_t size) +{ + return string_unescape(src, dst, size, UNESCAPE_ANY); +} + +static inline int string_unescape_any_inplace(char *buf) +{ + return string_unescape_any(buf, buf, 0); +} + #endif diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 28be08c09bab..77ebaa3dfa12 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1463,5 +1463,8 @@ source "lib/Kconfig.kgdb" source "lib/Kconfig.kmemcheck" +config TEST_STRING_HELPERS + tristate "Test functions located in the string_helpers module at runtime" + config TEST_KSTRTOX tristate "Test kstrto*() family of functions at runtime" diff --git a/lib/Makefile b/lib/Makefile index 6e2cc561f761..23c9a0fe74fc 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -22,8 +22,10 @@ lib-y += kobject.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ - string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ + gcd.o lcm.o list_sort.o uuid.o flex_array.o \ bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o +obj-y += string_helpers.o +obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o obj-y += kstrtox.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 1cffc223bff5..ed5c1454dd62 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -2,10 +2,12 @@ * Helpers for formatting and printing strings * * Copyright 31 August 2008 James Bottomley + * Copyright (C) 2013, Intel Corporation */ #include #include #include +#include #include /** @@ -66,3 +68,134 @@ int string_get_size(u64 size, const enum string_size_units units, return 0; } EXPORT_SYMBOL(string_get_size); + +static bool unescape_space(char **src, char **dst) +{ + char *p = *dst, *q = *src; + + switch (*q) { + case 'n': + *p = '\n'; + break; + case 'r': + *p = '\r'; + break; + case 't': + *p = '\t'; + break; + case 'v': + *p = '\v'; + break; + case 'f': + *p = '\f'; + break; + default: + return false; + } + *dst += 1; + *src += 1; + return true; +} + +static bool unescape_octal(char **src, char **dst) +{ + char *p = *dst, *q = *src; + u8 num; + + if (isodigit(*q) == 0) + return false; + + num = (*q++) & 7; + while (num < 32 && isodigit(*q) && (q - *src < 3)) { + num <<= 3; + num += (*q++) & 7; + } + *p = num; + *dst += 1; + *src = q; + return true; +} + +static bool unescape_hex(char **src, char **dst) +{ + char *p = *dst, *q = *src; + int digit; + u8 num; + + if (*q++ != 'x') + return false; + + num = digit = hex_to_bin(*q++); + if (digit < 0) + return false; + + digit = hex_to_bin(*q); + if (digit >= 0) { + q++; + num = (num << 4) | digit; + } + *p = num; + *dst += 1; + *src = q; + return true; +} + +static bool unescape_special(char **src, char **dst) +{ + char *p = *dst, *q = *src; + + switch (*q) { + case '\"': + *p = '\"'; + break; + case '\\': + *p = '\\'; + break; + case 'a': + *p = '\a'; + break; + case 'e': + *p = '\e'; + break; + default: + return false; + } + *dst += 1; + *src += 1; + return true; +} + +int string_unescape(char *src, char *dst, size_t size, unsigned int flags) +{ + char *out = dst; + + while (*src && --size) { + if (src[0] == '\\' && src[1] != '\0' && size > 1) { + src++; + size--; + + if (flags & UNESCAPE_SPACE && + unescape_space(&src, &out)) + continue; + + if (flags & UNESCAPE_OCTAL && + unescape_octal(&src, &out)) + continue; + + if (flags & UNESCAPE_HEX && + unescape_hex(&src, &out)) + continue; + + if (flags & UNESCAPE_SPECIAL && + unescape_special(&src, &out)) + continue; + + *out++ = '\\'; + } + *out++ = *src++; + } + *out = '\0'; + + return out - dst; +} +EXPORT_SYMBOL(string_unescape); diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c new file mode 100644 index 000000000000..6ac48de04c0e --- /dev/null +++ b/lib/test-string_helpers.c @@ -0,0 +1,103 @@ +/* + * Test cases for lib/string_helpers.c module. + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +struct test_string { + const char *in; + const char *out; + unsigned int flags; +}; + +static const struct test_string strings[] __initconst = { + { + .in = "\\f\\ \\n\\r\\t\\v", + .out = "\f\\ \n\r\t\v", + .flags = UNESCAPE_SPACE, + }, + { + .in = "\\40\\1\\387\\0064\\05\\040\\8a\\110\\777", + .out = " \001\00387\0064\005 \\8aH?7", + .flags = UNESCAPE_OCTAL, + }, + { + .in = "\\xv\\xa\\x2c\\xD\\x6f2", + .out = "\\xv\n,\ro2", + .flags = UNESCAPE_HEX, + }, + { + .in = "\\h\\\\\\\"\\a\\e\\", + .out = "\\h\\\"\a\e\\", + .flags = UNESCAPE_SPECIAL, + }, +}; + +static void __init test_string_unescape(unsigned int flags, bool inplace) +{ + char in[256]; + char out_test[256]; + char out_real[256]; + int i, p = 0, q_test = 0, q_real = sizeof(out_real); + + for (i = 0; i < ARRAY_SIZE(strings); i++) { + const char *s = strings[i].in; + int len = strlen(strings[i].in); + + /* Copy string to in buffer */ + memcpy(&in[p], s, len); + p += len; + + /* Copy expected result for given flags */ + if (flags & strings[i].flags) { + s = strings[i].out; + len = strlen(strings[i].out); + } + memcpy(&out_test[q_test], s, len); + q_test += len; + } + in[p++] = '\0'; + + /* Call string_unescape and compare result */ + if (inplace) { + memcpy(out_real, in, p); + if (flags == UNESCAPE_ANY) + q_real = string_unescape_any_inplace(out_real); + else + q_real = string_unescape_inplace(out_real, flags); + } else if (flags == UNESCAPE_ANY) { + q_real = string_unescape_any(in, out_real, q_real); + } else { + q_real = string_unescape(in, out_real, q_real, flags); + } + + if (q_real != q_test || memcmp(out_test, out_real, q_test)) { + pr_warn("Test failed: flags = %u\n", flags); + print_hex_dump(KERN_WARNING, "Input: ", + DUMP_PREFIX_NONE, 16, 1, in, p - 1, true); + print_hex_dump(KERN_WARNING, "Expected: ", + DUMP_PREFIX_NONE, 16, 1, out_test, q_test, true); + print_hex_dump(KERN_WARNING, "Got: ", + DUMP_PREFIX_NONE, 16, 1, out_real, q_real, true); + } +} + +static int __init test_string_helpers_init(void) +{ + unsigned int i; + + pr_info("Running tests...\n"); + for (i = 0; i < UNESCAPE_ANY + 1; i++) + test_string_unescape(i, false); + test_string_unescape(get_random_int() % (UNESCAPE_ANY + 1), true); + + return -EINVAL; +} +module_init(test_string_helpers_init); +MODULE_LICENSE("Dual BSD/GPL"); -- cgit v1.2.3-70-g09d2 From 576d742e4a0d0f1bab7950012addccb82fbc172a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 30 Apr 2013 15:27:31 -0700 Subject: staging: speakup: remove custom string_unescape_any_inplace There is generic implementation of the function to unescape strings. Signed-off-by: Andy Shevchenko Cc: Samuel Thibault Cc: Greg Kroah-Hartman Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/speakup/kobjects.c | 6 +++-- drivers/staging/speakup/speakup.h | 1 - drivers/staging/speakup/varhandlers.c | 46 ----------------------------------- 3 files changed, 4 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index d6d9264e4ca7..943b6c134a22 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -417,7 +418,7 @@ static ssize_t synth_direct_store(struct kobject *kobj, bytes = min_t(size_t, len, 250); strncpy(tmp, ptr, bytes); tmp[bytes] = '\0'; - spk_xlate(tmp); + string_unescape_any_inplace(tmp); synth_printf("%s", tmp); ptr += bytes; len -= bytes; @@ -605,7 +606,8 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, if (param->data == NULL) return 0; ret = 0; - cp = spk_xlate((char *) buf); + cp = (char *)buf; + string_unescape_any_inplace(cp); spk_lock(flags); switch (param->var_type) { diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h index c387a02fc1c2..0126f714821a 100644 --- a/drivers/staging/speakup/speakup.h +++ b/drivers/staging/speakup/speakup.h @@ -54,7 +54,6 @@ void spk_get_index_count(int *linecount, int *sentcount); extern int spk_set_key_info(const u_char *key_info, u_char *k_buffer); extern char *spk_strlwr(char *s); extern char *spk_s2uchar(char *start, char *dest); -extern char *spk_xlate(char *s); extern int speakup_kobj_init(void); extern void speakup_kobj_exit(void); extern int spk_chartab_get_value(char *keyword); diff --git a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c index 0099cb12e560..7f6288fc2299 100644 --- a/drivers/staging/speakup/varhandlers.c +++ b/drivers/staging/speakup/varhandlers.c @@ -328,49 +328,3 @@ char *spk_s2uchar(char *start, char *dest) *dest = (u_char)val; return start; } - -char *spk_xlate(char *s) -{ - static const char finds[] = "nrtvafe"; - static const char subs[] = "\n\r\t\013\001\014\033"; - static const char hx[] = "0123456789abcdefABCDEF"; - char *p = s, *p1, *p2, c; - int num; - while ((p = strchr(p, '\\'))) { - p1 = p+1; - p2 = strchr(finds, *p1); - if (p2) { - *p++ = subs[p2-finds]; - p1++; - } else if (*p1 >= '0' && *p1 <= '7') { - num = (*p1++)&7; - while (num < 32 && *p1 >= '0' && *p1 <= '7') { - num <<= 3; - num += (*p1++)&7; - } - *p++ = num; - } else if (*p1 == 'x' && - strchr(hx, p1[1]) && strchr(hx, p1[2])) { - p1++; - c = *p1++; - if (c > '9') - c = (c - '7') & 0x0f; - else - c -= '0'; - num = c << 4; - c = *p1++; - if (c > '9') - c = (c-'7')&0x0f; - else - c -= '0'; - num += c; - *p++ = num; - } else - *p++ = *p1++; - p2 = p; - while (*p1) - *p2++ = *p1++; - *p2 = '\0'; - } - return s; -} -- cgit v1.2.3-70-g09d2 From 79bae42d51a5d498500c890c19ef76df41d2bf59 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 30 Apr 2013 15:27:46 -0700 Subject: dmi_scan: refactor dmi_scan_machine(), {smbios,dmi}_present() Move the calls to memcpy_fromio() up into the loop in dmi_scan_machine(), and move the signature checks back down into dmi_decode(). We need to check at 16-byte intervals but keep a 32-byte buffer for an SMBIOS entry, so shift the buffer after each iteration. Merge smbios_present() into dmi_present(), so we look for an SMBIOS signature at the beginning of the given buffer and then for a DMI signature at an offset of 16 bytes. [artem.savkov@gmail.com: use proper buf type in dmi_present()] Signed-off-by: Ben Hutchings Reported-by: Tim McGrath Tested-by: Tim Mcgrath Cc: Zhenzhong Duan Signed-off-by: Artem Savkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/firmware/dmi_scan.c | 80 +++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 98c62081c034..b95159b33c39 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -419,22 +419,45 @@ static void __init dmi_format_ids(char *buf, size_t len) dmi_get_system_info(DMI_BIOS_DATE)); } -static int __init dmi_present(const char __iomem *p) +static int __init dmi_present(const u8 *buf) { - u8 buf[15]; + int smbios_ver; - memcpy_fromio(buf, p, 15); - if (dmi_checksum(buf, 15)) { + if (memcmp(buf, "_SM_", 4) == 0 && + buf[5] < 32 && dmi_checksum(buf, buf[5])) { + smbios_ver = (buf[6] << 8) + buf[7]; + + /* Some BIOS report weird SMBIOS version, fix that up */ + switch (smbios_ver) { + case 0x021F: + case 0x0221: + pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", + smbios_ver & 0xFF, 3); + smbios_ver = 0x0203; + break; + case 0x0233: + pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6); + smbios_ver = 0x0206; + break; + } + } else { + smbios_ver = 0; + } + + buf += 16; + + if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) { dmi_num = (buf[13] << 8) | buf[12]; dmi_len = (buf[7] << 8) | buf[6]; dmi_base = (buf[11] << 24) | (buf[10] << 16) | (buf[9] << 8) | buf[8]; if (dmi_walk_early(dmi_decode) == 0) { - if (dmi_ver) + if (smbios_ver) { + dmi_ver = smbios_ver; pr_info("SMBIOS %d.%d present.\n", dmi_ver >> 8, dmi_ver & 0xFF); - else { + } else { dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F); pr_info("Legacy DMI %d.%d present.\n", @@ -445,40 +468,14 @@ static int __init dmi_present(const char __iomem *p) return 0; } } - dmi_ver = 0; - return 1; -} -static int __init smbios_present(const char __iomem *p) -{ - u8 buf[32]; - - memcpy_fromio(buf, p, 32); - if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) { - dmi_ver = (buf[6] << 8) + buf[7]; - - /* Some BIOS report weird SMBIOS version, fix that up */ - switch (dmi_ver) { - case 0x021F: - case 0x0221: - pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", - dmi_ver & 0xFF, 3); - dmi_ver = 0x0203; - break; - case 0x0233: - pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6); - dmi_ver = 0x0206; - break; - } - return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16); - } return 1; } void __init dmi_scan_machine(void) { char __iomem *p, *q; - int rc; + char buf[32]; if (efi_enabled(EFI_CONFIG_TABLES)) { if (efi.smbios == EFI_INVALID_TABLE_ADDR) @@ -491,10 +488,10 @@ void __init dmi_scan_machine(void) p = dmi_ioremap(efi.smbios, 32); if (p == NULL) goto error; - - rc = smbios_present(p); + memcpy_fromio(buf, p, 32); dmi_iounmap(p, 32); - if (!rc) { + + if (!dmi_present(buf)) { dmi_available = 1; goto out; } @@ -509,18 +506,15 @@ void __init dmi_scan_machine(void) if (p == NULL) goto error; + memset(buf, 0, 16); for (q = p; q < p + 0x10000; q += 16) { - if (memcmp(q, "_SM_", 4) == 0 && q - p <= 0xFFE0) - rc = smbios_present(q); - else if (memcmp(q, "_DMI_", 5) == 0) - rc = dmi_present(q); - else - continue; - if (!rc) { + memcpy_fromio(buf + 16, q, 16); + if (!dmi_present(buf)) { dmi_available = 1; dmi_iounmap(p, 0x10000); goto out; } + memcpy(buf, buf + 16, 16); } dmi_iounmap(p, 0x10000); } -- cgit v1.2.3-70-g09d2 From 9151b3982dafaa87bca3834c4d20db831ca98bcb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 30 Apr 2013 15:27:47 -0700 Subject: i2o: check copy_from_user() size parameter Limit the size of the copy so we don't corrupt memory. Hopefully this can only be called by root, but fixing this makes the static checkers happier. Signed-off-by: Dan Carpenter Cc: Jiri Kosina Cc: Masanari Iida Cc: Alan Cox Cc: Guenter Roeck Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/message/i2o/i2o_config.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index 5451beff183f..a60c188c2bd9 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c @@ -687,6 +687,11 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, } size = size >> 16; size *= 4; + if (size > sizeof(rmsg)) { + rcode = -EINVAL; + goto sg_list_cleanup; + } + /* Copy in the user's I2O command */ if (copy_from_user(rmsg, user_msg, size)) { rcode = -EFAULT; @@ -922,6 +927,11 @@ static int i2o_cfg_passthru(unsigned long arg) } size = size >> 16; size *= 4; + if (size > sizeof(rmsg)) { + rcode = -EFAULT; + goto sg_list_cleanup; + } + /* Copy in the user's I2O command */ if (copy_from_user(rmsg, user_msg, size)) { rcode = -EFAULT; -- cgit v1.2.3-70-g09d2 From 078be02b80359a541928c899c2631f39628f56df Mon Sep 17 00:00:00 2001 From: Michal Belczyk Date: Tue, 30 Apr 2013 15:28:28 -0700 Subject: nbd: increase default and max request sizes Raise the default max request size for nbd to 128KB (from 127KB) to get it 4KB aligned. This patch also allows the max request size to be increased (via /sys/block/nbd/queue/max_sectors_kb) to 32MB. The patch makes nbd network traffic more efficient by: - reducing request fragmentation (4KB alignment) - reducing the number of requests (fewer round trips, less network overhead) Especially in high latency networks, larger request size can make a dramatic Signed-off-by: Paul Clements Signed-off-by: Michal Belczyk Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/nbd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 7fecc784be01..037288e7874d 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -856,6 +856,8 @@ static int __init nbd_init(void) disk->queue->limits.discard_granularity = 512; disk->queue->limits.max_discard_sectors = UINT_MAX; disk->queue->limits.discard_zeroes_data = 0; + blk_queue_max_hw_sectors(disk->queue, 65536); + disk->queue->limits.max_sectors = 256; } if (register_blkdev(NBD_MAJOR, "nbd")) { -- cgit v1.2.3-70-g09d2 From 60abc786dd3b5d6917d63fd789c9fed772f65039 Mon Sep 17 00:00:00 2001 From: Mihnea Dobrescu-Balaur Date: Tue, 30 Apr 2013 15:28:29 -0700 Subject: aoe: replace kmalloc and then memcpy with kmemdup Signed-off-by: Mihnea Dobrescu-Balaur Cc: Ed Cashin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/aoe/aoechr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 42e67ad6bd20..ab41be625a53 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -139,13 +139,12 @@ bail: spin_unlock_irqrestore(&emsgs_lock, flags); return; } - mp = kmalloc(n, GFP_ATOMIC); + mp = kmemdup(msg, n, GFP_ATOMIC); if (mp == NULL) { printk(KERN_ERR "aoe: allocation failure, len=%ld\n", n); goto bail; } - memcpy(mp, msg, n); em->msg = mp; em->flags |= EMFL_VALID; em->len = n; -- cgit v1.2.3-70-g09d2 From 1a0f39997caf3e1edc7e5b7da168b91c32760ccb Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 30 Apr 2013 15:28:30 -0700 Subject: pps: hide more configuration symbols behind CONFIG_PPS Make CONFIG_PPS_DEBUG and CONFIG_NTP_PPS be hidden if CONFIG_PPS is not selected, so that we are not prompted for these configuration options if CONFIG_PPS is not set. Signed-off-by: Florian Fainelli Cc: Rodolfo Giometti Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pps/Kconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig index 982d16b5a846..7512e98e9311 100644 --- a/drivers/pps/Kconfig +++ b/drivers/pps/Kconfig @@ -20,10 +20,10 @@ config PPS To compile this driver as a module, choose M here: the module will be called pps_core.ko. +if PPS config PPS_DEBUG bool "PPS debugging messages" - depends on PPS help Say Y here if you want the PPS support to produce a bunch of debug messages to the system log. Select this if you are having a @@ -31,13 +31,15 @@ config PPS_DEBUG config NTP_PPS bool "PPS kernel consumer support" - depends on PPS && !NO_HZ + depends on !NO_HZ help This option adds support for direct in-kernel time synchronization using an external PPS signal. It doesn't work on tickless systems at the moment. +endif + source drivers/pps/clients/Kconfig source drivers/pps/generators/Kconfig -- cgit v1.2.3-70-g09d2 From 97439d0f84942d3031545e80852dde09457136c6 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 30 Apr 2013 15:28:31 -0700 Subject: pps: pps_kc_hardpps_lock can be static drivers/pps/kc.c:37:1: sparse: symbol 'pps_kc_hardpps_lock' was not declared. Should it be static? drivers/pps/kc.c:39:19: sparse: symbol 'pps_kc_hardpps_dev' was not declared. Should it be static? drivers/pps/kc.c:40:5: sparse: symbol 'pps_kc_hardpps_mode' was not declared. Should it be static? Signed-off-by: Fengguang Wu Cc: Rodolfo Giometti Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pps/kc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pps/kc.c b/drivers/pps/kc.c index 079e930b1938..e219db1f1c84 100644 --- a/drivers/pps/kc.c +++ b/drivers/pps/kc.c @@ -34,10 +34,10 @@ */ /* state variables to bind kernel consumer */ -DEFINE_SPINLOCK(pps_kc_hardpps_lock); +static DEFINE_SPINLOCK(pps_kc_hardpps_lock); /* PPS API (RFC 2783): current source and mode for kernel consumer */ -struct pps_device *pps_kc_hardpps_dev; /* unique pointer to device */ -int pps_kc_hardpps_mode; /* mode bits for kernel consumer */ +static struct pps_device *pps_kc_hardpps_dev; /* unique pointer to device */ +static int pps_kc_hardpps_mode; /* mode bits for kernel consumer */ /* pps_kc_bind - control PPS kernel consumer binding * @pps: the PPS source -- cgit v1.2.3-70-g09d2 From 8d46fa11790e012d991495148f2d16cdbf4ee864 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 30 Apr 2013 15:28:34 -0700 Subject: drivers/memstick/host/r592.c: make r592_pm_ops static r592_pm_ops is not exported. Also, CONFIG_PM_SLEEP is used to remove unnecessary ifdefs. Signed-off-by: Jingoo Han Cc: Maxim Levitsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/memstick/host/r592.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index a7c5b31c0d50..9718661c1fb6 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -847,7 +847,7 @@ static void r592_remove(struct pci_dev *pdev) dev->dummy_dma_page_physical_address); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int r592_suspend(struct device *core_dev) { struct pci_dev *pdev = to_pci_dev(core_dev); @@ -870,10 +870,10 @@ static int r592_resume(struct device *core_dev) r592_update_card_detect(dev); return 0; } - -SIMPLE_DEV_PM_OPS(r592_pm_ops, r592_suspend, r592_resume); #endif +static SIMPLE_DEV_PM_OPS(r592_pm_ops, r592_suspend, r592_resume); + MODULE_DEVICE_TABLE(pci, r592_pci_id_tbl); static struct pci_driver r852_pci_driver = { @@ -881,9 +881,7 @@ static struct pci_driver r852_pci_driver = { .id_table = r592_pci_id_tbl, .probe = r592_probe, .remove = r592_remove, -#ifdef CONFIG_PM .driver.pm = &r592_pm_ops, -#endif }; static __init int r592_module_init(void) -- cgit v1.2.3-70-g09d2 From 0ece1bbf4c280a4e886709ebf21d7df35a638a82 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 30 Apr 2013 15:28:35 -0700 Subject: drivers/w1/slaves/w1_bq27000.c: fix the error handling in w1_bq27000_add_slave() Use platform_device_put() instead of platform_device_unregister() if platform_device_add() fails, and also add the return value check of platform_device_add_data(). Signed-off-by: Wei Yongjun Cc: Evgeniy Polyakov Cc: Greg KH Cc: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/slaves/w1_bq27000.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c index 773dca5beafe..afbefed5f2c9 100644 --- a/drivers/w1/slaves/w1_bq27000.c +++ b/drivers/w1/slaves/w1_bq27000.c @@ -57,6 +57,8 @@ static int w1_bq27000_add_slave(struct w1_slave *sl) ret = platform_device_add_data(pdev, &bq27000_battery_info, sizeof(bq27000_battery_info)); + if (ret) + goto pdev_add_failed; pdev->dev.parent = &sl->dev; ret = platform_device_add(pdev); @@ -68,7 +70,7 @@ static int w1_bq27000_add_slave(struct w1_slave *sl) goto success; pdev_add_failed: - platform_device_unregister(pdev); + platform_device_put(pdev); success: return ret; } -- cgit v1.2.3-70-g09d2 From c5cfedf234fd5ba457c404bf42b6e6aea23b1e69 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 30 Apr 2013 15:28:36 -0700 Subject: drivers/w1/slaves/w1_ds2780.c: fix the error handling in w1_ds2780_add_slave() Use platform_device_put() instead of platform_device_unregister() if platform_device_add() fail, and platform_device_del() should be used in the error handling case after platform_device_add() success. Signed-off-by: Wei Yongjun Cc: Evgeniy Polyakov Cc: Greg KH Cc: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/slaves/w1_ds2780.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c index 7b09307de0ef..98ed9c49cf50 100644 --- a/drivers/w1/slaves/w1_ds2780.c +++ b/drivers/w1/slaves/w1_ds2780.c @@ -141,8 +141,9 @@ static int w1_ds2780_add_slave(struct w1_slave *sl) return 0; bin_attr_failed: + platform_device_del(pdev); pdev_add_failed: - platform_device_unregister(pdev); + platform_device_put(pdev); pdev_alloc_failed: ida_simple_remove(&bat_ida, id); noid: -- cgit v1.2.3-70-g09d2 From c28d6f2ddb10fd2b359083e89ae583c6c062e35f Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 30 Apr 2013 15:28:37 -0700 Subject: drivers/w1/slaves/w1_ds2781.c: fix the error handling in w1_ds2781_add_slave() Use platform_device_put() instead of platform_device_unregister() if platform_device_add() fail, and platform_device_del() should be used in the error handling case after platform_device_add() success. Signed-off-by: Wei Yongjun Cc: Evgeniy Polyakov Cc: Greg KH Cc: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/slaves/w1_ds2781.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c index 877daf74159c..5140d7be67ab 100644 --- a/drivers/w1/slaves/w1_ds2781.c +++ b/drivers/w1/slaves/w1_ds2781.c @@ -139,8 +139,9 @@ static int w1_ds2781_add_slave(struct w1_slave *sl) return 0; bin_attr_failed: + platform_device_del(pdev); pdev_add_failed: - platform_device_unregister(pdev); + platform_device_put(pdev); pdev_alloc_failed: ida_simple_remove(&bat_ida, id); noid: -- cgit v1.2.3-70-g09d2 From 4d10e0f2dd42b950448c13715f88edfce82a0975 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 30 Apr 2013 15:28:38 -0700 Subject: drivers/w1/slaves/w1_ds2760.c: fix the error handling in w1_ds2760_add_slave() Use platform_device_put() instead of platform_device_unregister() if platform_device_add() fail, and platform_device_del() should be used in the error handling case after platform_device_add() success. Signed-off-by: Wei Yongjun Cc: Evgeniy Polyakov Cc: Greg KH Cc: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/slaves/w1_ds2760.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index aa7bd5fa2fa8..e86a69dc411e 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c @@ -148,8 +148,9 @@ static int w1_ds2760_add_slave(struct w1_slave *sl) goto success; bin_attr_failed: + platform_device_del(pdev); pdev_add_failed: - platform_device_unregister(pdev); + platform_device_put(pdev); pdev_alloc_failed: ida_simple_remove(&bat_ida, id); noid: -- cgit v1.2.3-70-g09d2 From 966f3096b18bf13385799ef745e114a8f292ed69 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 30 Apr 2013 15:28:44 -0700 Subject: kconfig menu: move Virtualization drivers near other virtualization options Make virtualization drivers be logically grouped together (physically near each other) in the kconfig menu by moving "Virtualization drivers" to be near "Virtio drivers", Microsort Hyper-V, and Xen driver support. This is just a user-friendly, visual search change. Signed-off-by: Randy Dunlap Cc: Alexander Graf Cc: Stuart Yoder Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/Kconfig b/drivers/Kconfig index 78a956e286e6..8d96238549fa 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -120,6 +120,8 @@ source "drivers/vfio/Kconfig" source "drivers/vlynq/Kconfig" +source "drivers/virt/Kconfig" + source "drivers/virtio/Kconfig" source "drivers/hv/Kconfig" @@ -144,8 +146,6 @@ source "drivers/remoteproc/Kconfig" source "drivers/rpmsg/Kconfig" -source "drivers/virt/Kconfig" - source "drivers/devfreq/Kconfig" source "drivers/extcon/Kconfig" -- cgit v1.2.3-70-g09d2 From 7b6b99a02a8acfa8e71a990198c2ad0b9cc5cd71 Mon Sep 17 00:00:00 2001 From: "zhangwei(Jovi)" Date: Tue, 30 Apr 2013 15:28:56 -0700 Subject: ethernet/emac/sysrq: fix inconstistent help message of sysrq key Currently help message of /proc/sysrq-trigger highlight its upper-case characters, like below: SysRq : HELP : loglevel(0-9) reBoot Crash terminate-all-tasks(E) memory-full-oom-kill(F) kill-all-tasks(I) ... this would confuse user trigger sysrq by upper-case character, which is inconsistent with the real lower-case character registed key. This inconsistent help message will also lead more confused when 26 upper-case letters put into use in future. This patch ethernet emac sysrq key: "emac(c)" Signed-off-by: zhangwei(Jovi) Cc: Josh Boyer Cc: Thadeu Lima de Souza Cascardo Cc: David Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/ethernet/ibm/emac/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ibm/emac/debug.c b/drivers/net/ethernet/ibm/emac/debug.c index b16b4828b64d..a559f326bf63 100644 --- a/drivers/net/ethernet/ibm/emac/debug.c +++ b/drivers/net/ethernet/ibm/emac/debug.c @@ -245,7 +245,7 @@ static void emac_sysrq_handler(int key) static struct sysrq_key_op emac_sysrq_op = { .handler = emac_sysrq_handler, - .help_msg = "emaC", + .help_msg = "emac(c)", .action_msg = "Show EMAC(s) status", }; -- cgit v1.2.3-70-g09d2