diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-11-23 09:04:05 +0100 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-11-23 09:04:05 +0100 | 
| commit | 92907cbbef8625bb3998d1eb385fc88f23c97a3f (patch) | |
| tree | 15626ff9287e37c3cb81c7286d6db5a7fd77c854 /net/sunrpc/cache.c | |
| parent | 15fbfccfe92c62ae8d1ecc647c44157ed01ac02e (diff) | |
| parent | 1ec218373b8ebda821aec00bb156a9c94fad9cd4 (diff) | |
Merge tag 'v4.4-rc2' into drm-intel-next-queued
Linux 4.4-rc2
Backmerge to get at
commit 1b0e3a049efe471c399674fd954500ce97438d30
Author: Imre Deak <imre.deak@intel.com>
Date:   Thu Nov 5 23:04:11 2015 +0200
    drm/i915/skl: disable display side power well support for now
so that we can proplery re-eanble skl power wells in -next.
Conflicts are just adjacent lines changed, except for intel_fbdev.c
where we need to interleave the changs. Nothing nefarious.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'net/sunrpc/cache.c')
| -rw-r--r-- | net/sunrpc/cache.c | 53 | 
1 files changed, 40 insertions, 13 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 4a2340a54401..5e4f815c2b34 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -41,13 +41,16 @@  static bool cache_defer_req(struct cache_req *req, struct cache_head *item);  static void cache_revisit_request(struct cache_head *item); -static void cache_init(struct cache_head *h) +static void cache_init(struct cache_head *h, struct cache_detail *detail)  {  	time_t now = seconds_since_boot();  	INIT_HLIST_NODE(&h->cache_list);  	h->flags = 0;  	kref_init(&h->ref);  	h->expiry_time = now + CACHE_NEW_EXPIRY; +	if (now <= detail->flush_time) +		/* ensure it isn't already expired */ +		now = detail->flush_time + 1;  	h->last_refresh = now;  } @@ -81,7 +84,7 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,  	 * we might get lose if we need to  	 * cache_put it soon.  	 */ -	cache_init(new); +	cache_init(new, detail);  	detail->init(new, key);  	write_lock(&detail->hash_lock); @@ -116,10 +119,15 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);  static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch); -static void cache_fresh_locked(struct cache_head *head, time_t expiry) +static void cache_fresh_locked(struct cache_head *head, time_t expiry, +			       struct cache_detail *detail)  { +	time_t now = seconds_since_boot(); +	if (now <= detail->flush_time) +		/* ensure it isn't immediately treated as expired */ +		now = detail->flush_time + 1;  	head->expiry_time = expiry; -	head->last_refresh = seconds_since_boot(); +	head->last_refresh = now;  	smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */  	set_bit(CACHE_VALID, &head->flags);  } @@ -149,7 +157,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,  				set_bit(CACHE_NEGATIVE, &old->flags);  			else  				detail->update(old, new); -			cache_fresh_locked(old, new->expiry_time); +			cache_fresh_locked(old, new->expiry_time, detail);  			write_unlock(&detail->hash_lock);  			cache_fresh_unlocked(old, detail);  			return old; @@ -162,7 +170,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,  		cache_put(old, detail);  		return NULL;  	} -	cache_init(tmp); +	cache_init(tmp, detail);  	detail->init(tmp, old);  	write_lock(&detail->hash_lock); @@ -173,8 +181,8 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,  	hlist_add_head(&tmp->cache_list, &detail->hash_table[hash]);  	detail->entries++;  	cache_get(tmp); -	cache_fresh_locked(tmp, new->expiry_time); -	cache_fresh_locked(old, 0); +	cache_fresh_locked(tmp, new->expiry_time, detail); +	cache_fresh_locked(old, 0, detail);  	write_unlock(&detail->hash_lock);  	cache_fresh_unlocked(tmp, detail);  	cache_fresh_unlocked(old, detail); @@ -219,7 +227,8 @@ static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h  	rv = cache_is_valid(h);  	if (rv == -EAGAIN) {  		set_bit(CACHE_NEGATIVE, &h->flags); -		cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY); +		cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY, +				   detail);  		rv = -ENOENT;  	}  	write_unlock(&detail->hash_lock); @@ -487,10 +496,13 @@ EXPORT_SYMBOL_GPL(cache_flush);  void cache_purge(struct cache_detail *detail)  { -	detail->flush_time = LONG_MAX; +	time_t now = seconds_since_boot(); +	if (detail->flush_time >= now) +		now = detail->flush_time + 1; +	/* 'now' is the maximum value any 'last_refresh' can have */ +	detail->flush_time = now;  	detail->nextcheck = seconds_since_boot();  	cache_flush(); -	detail->flush_time = 1;  }  EXPORT_SYMBOL_GPL(cache_purge); @@ -1436,6 +1448,7 @@ static ssize_t write_flush(struct file *file, const char __user *buf,  {  	char tbuf[20];  	char *bp, *ep; +	time_t then, now;  	if (*ppos || count > sizeof(tbuf)-1)  		return -EINVAL; @@ -1447,8 +1460,22 @@ static ssize_t write_flush(struct file *file, const char __user *buf,  		return -EINVAL;  	bp = tbuf; -	cd->flush_time = get_expiry(&bp); -	cd->nextcheck = seconds_since_boot(); +	then = get_expiry(&bp); +	now = seconds_since_boot(); +	cd->nextcheck = now; +	/* Can only set flush_time to 1 second beyond "now", or +	 * possibly 1 second beyond flushtime.  This is because +	 * flush_time never goes backwards so it mustn't get too far +	 * ahead of time. +	 */ +	if (then >= now) { +		/* Want to flush everything, so behave like cache_purge() */ +		if (cd->flush_time >= now) +			now = cd->flush_time + 1; +		then = now; +	} + +	cd->flush_time = then;  	cache_flush();  	*ppos += count;  | 
