2017-02-05 13:41:59

by Kinglong Mee

[permalink] [raw]
Subject: [PATCH] SUNRPC: Drop all entries left in cache_detail when destroy

User always free the cache_detail after sunrpc_destroy_cache_detail(),
so, it must cleanup up entries that left in the cache_detail,
otherwise, NULL reference may be caused when using the left entries.

Signed-off-by: Kinglong Mee <[email protected]>
---
net/sunrpc/cache.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 8147e8d..a2c6fec 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -359,14 +359,28 @@ EXPORT_SYMBOL_GPL(sunrpc_init_cache_detail);

void sunrpc_destroy_cache_detail(struct cache_detail *cd)
{
+ struct cache_head *ch = NULL;
+ struct hlist_head *head = NULL;
+ struct hlist_node *tmp = NULL;
+ int i = 0;
+
cache_purge(cd);
spin_lock(&cache_list_lock);
write_lock(&cd->hash_lock);
+
if (cd->entries) {
- write_unlock(&cd->hash_lock);
- spin_unlock(&cache_list_lock);
- goto out;
+ printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
+ for (i = 0; i < cd->hash_size; i++) {
+ head = &cd->hash_table[i];
+ hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
+ hlist_del_init(&ch->cache_list);
+ set_bit(CACHE_CLEANED, &ch->flags);
+ cache_fresh_unlocked(ch, cd);
+ cache_put(ch, cd);
+ }
+ }
}
+
if (current_detail == cd)
current_detail = NULL;
list_del_init(&cd->others);
@@ -376,9 +390,6 @@ void sunrpc_destroy_cache_detail(struct cache_detail *cd)
/* module must be being unloaded so its safe to kill the worker */
cancel_delayed_work_sync(&cache_cleaner);
}
- return;
-out:
- printk(KERN_ERR "RPC: failed to unregister %s cache\n", cd->name);
}
EXPORT_SYMBOL_GPL(sunrpc_destroy_cache_detail);

--
2.9.3



2017-02-05 14:14:51

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] SUNRPC: Drop all entries left in cache_detail when destroy

Hi Kinglong,

[auto build test WARNING on nfsd/nfsd-next]
[also build test WARNING on v4.10-rc6 next-20170203]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Kinglong-Mee/SUNRPC-Drop-all-entries-left-in-cache_detail-when-destroy/20170205-214442
base: git://linux-nfs.org/~bfields/linux.git nfsd-next
config: m68k-sun3_defconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 4.9.0
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=m68k

All warnings (new ones prefixed by >>):

net/sunrpc/cache.c: In function 'sunrpc_destroy_cache_detail':
>> net/sunrpc/cache.c:372:3: warning: format '%d' expects argument of type 'int', but argument 2 has type 'char *' [-Wformat=]
printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
^
>> net/sunrpc/cache.c:372:3: warning: format '%s' expects a matching 'char *' argument [-Wformat=]

vim +372 net/sunrpc/cache.c

356 queue_delayed_work(system_power_efficient_wq, &cache_cleaner, 0);
357 }
358 EXPORT_SYMBOL_GPL(sunrpc_init_cache_detail);
359
360 void sunrpc_destroy_cache_detail(struct cache_detail *cd)
361 {
362 struct cache_head *ch = NULL;
363 struct hlist_head *head = NULL;
364 struct hlist_node *tmp = NULL;
365 int i = 0;
366
367 cache_purge(cd);
368 spin_lock(&cache_list_lock);
369 write_lock(&cd->hash_lock);
370
371 if (cd->entries) {
> 372 printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
373 for (i = 0; i < cd->hash_size; i++) {
374 head = &cd->hash_table[i];
375 hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
376 hlist_del_init(&ch->cache_list);
377 set_bit(CACHE_CLEANED, &ch->flags);
378 cache_fresh_unlocked(ch, cd);
379 cache_put(ch, cd);
380 }

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (2.18 kB)
.config.gz (11.42 kB)
Download all attachments

2017-02-05 14:14:51

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] SUNRPC: Drop all entries left in cache_detail when destroy

Hi Kinglong,

[auto build test WARNING on nfsd/nfsd-next]
[also build test WARNING on v4.10-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Kinglong-Mee/SUNRPC-Drop-all-entries-left-in-cache_detail-when-destroy/20170205-214442
base: git://linux-nfs.org/~bfields/linux.git nfsd-next
config: i386-randconfig-x004-201706 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386

All warnings (new ones prefixed by >>):

In file included from include/linux/printk.h:6:0,
from include/linux/kernel.h:13,
from include/linux/list.h:8,
from include/linux/wait.h:6,
from include/linux/fs.h:5,
from net/sunrpc/cache.c:14:
net/sunrpc/cache.c: In function 'sunrpc_destroy_cache_detail':
>> include/linux/kern_levels.h:4:18: warning: format '%d' expects argument of type 'int', but argument 2 has type 'char *' [-Wformat=]
#define KERN_SOH "\001" /* ASCII Start Of Header */
^
include/linux/kern_levels.h:10:18: note: in expansion of macro 'KERN_SOH'
#define KERN_ERR KERN_SOH "3" /* error conditions */
^~~~~~~~
>> net/sunrpc/cache.c:372:10: note: in expansion of macro 'KERN_ERR'
printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
^~~~~~~~
include/linux/kern_levels.h:4:18: warning: format '%s' expects a matching 'char *' argument [-Wformat=]
#define KERN_SOH "\001" /* ASCII Start Of Header */
^
include/linux/kern_levels.h:10:18: note: in expansion of macro 'KERN_SOH'
#define KERN_ERR KERN_SOH "3" /* error conditions */
^~~~~~~~
>> net/sunrpc/cache.c:372:10: note: in expansion of macro 'KERN_ERR'
printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
^~~~~~~~

vim +/KERN_ERR +372 net/sunrpc/cache.c

356 queue_delayed_work(system_power_efficient_wq, &cache_cleaner, 0);
357 }
358 EXPORT_SYMBOL_GPL(sunrpc_init_cache_detail);
359
360 void sunrpc_destroy_cache_detail(struct cache_detail *cd)
361 {
362 struct cache_head *ch = NULL;
363 struct hlist_head *head = NULL;
364 struct hlist_node *tmp = NULL;
365 int i = 0;
366
367 cache_purge(cd);
368 spin_lock(&cache_list_lock);
369 write_lock(&cd->hash_lock);
370
371 if (cd->entries) {
> 372 printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
373 for (i = 0; i < cd->hash_size; i++) {
374 head = &cd->hash_table[i];
375 hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
376 hlist_del_init(&ch->cache_list);
377 set_bit(CACHE_CLEANED, &ch->flags);
378 cache_fresh_unlocked(ch, cd);
379 cache_put(ch, cd);
380 }

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (3.07 kB)
.config.gz (27.02 kB)
Download all attachments