[sheepdog] [PATCH 2/6] sockfd: implement shrinking mechanism for handling EMFILE

Hitoshi Mitake mitake.hitoshi at gmail.com
Mon Aug 19 10:10:04 CEST 2013


At Mon, 19 Aug 2013 14:36:49 +0800,
Liu Yuan wrote:
> 
> On Wed, Aug 14, 2013 at 01:27:37AM +0900, Hitoshi Mitake wrote:
> > sockfd is a big fd consumer and cached fds should be closed when sheep
> > faces EMFILE. This patch adds a new function, sockfd_shrink(), for
> > closing unused cached fds.
> > 
> > Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
> > ---
> >  include/sockfd_cache.h |  1 +
> >  lib/sockfd_cache.c     | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 63 insertions(+)
> > 
> > diff --git a/include/sockfd_cache.h b/include/sockfd_cache.h
> > index d91c56a..aaceaa7 100644
> > --- a/include/sockfd_cache.h
> > +++ b/include/sockfd_cache.h
> > @@ -12,6 +12,7 @@ void sockfd_cache_add(const struct node_id *nid);
> >  void sockfd_cache_add_group(const struct sd_node *nodes, int nr);
> >  
> >  int sockfd_init(void);
> > +bool sockfd_shrink(void);
> >  
> >  /* sockfd_cache */
> >  struct sockfd {
> > diff --git a/lib/sockfd_cache.c b/lib/sockfd_cache.c
> > index c9404ea..ef3fa7d 100644
> > --- a/lib/sockfd_cache.c
> > +++ b/lib/sockfd_cache.c
> > @@ -47,6 +47,12 @@ static struct sockfd_cache sockfd_cache = {
> >  };
> >  
> >  /*
> > + * shrink_head: used by shrink_sockfd() for fair shrinking
> > + * protected by sockfd_cache.lock
> > + */
> > +static struct rb_node *shrink_head;
> 
> Remove shrink_head please, let's start with a simple round rabin shrinker
> first. By the way, if we need a more complex shrinking approach, I'd suggest use
> LRU list to emit least recently used fd(s). But for now, LRU is kind of over
> kill.

OK, I remove shrink_head in the next version. And agree with employing
LRU is overkill for now.

> 
> > +
> > +/*
> >   * Suppose request size from Guest is 512k, then 4M / 512k = 8, so at
> >   * most 8 requests can be issued to the same sheep object. Based on this
> >   * assumption, '8' would be effecient for servers that only host 2~4
> > @@ -208,6 +214,9 @@ static bool sockfd_cache_destroy(const struct node_id *nid)
> >  	rb_erase(&entry->rb, &sockfd_cache.root);
> >  	sd_unlock(&sockfd_cache.lock);
> >  
> > +	if (&entry->rb == shrink_head)
> > +		shrink_head = rb_next(&entry->rb);
> > +
> >  	destroy_all_slots(entry);
> >  	free_cache_entry(entry);
> >  
> > @@ -529,3 +538,56 @@ void sockfd_cache_del(const struct node_id *nid, struct sockfd *sfd)
> >  	sockfd_cache_del_node(nid);
> >  	free(sfd);
> >  }
> > +
> > +bool sockfd_shrink(void)
> > +{
> > +	bool ret = false;
> > +	struct rb_node *p, *first;
> > +
> > +	sd_write_lock(&sockfd_cache.lock);
> > +
> > +	p = shrink_head ? shrink_head : rb_first(&sockfd_cache.root);
> > +	if (!p) {
> > +		sd_debug("There's no sockfd");
> > +		goto out;
> > +	}
> > +
> > +	first = p;
> > +	do {
> > +		struct sockfd_cache_entry *entry =
> > +			rb_entry(p, struct sockfd_cache_entry, rb);
> > +
> > +		for (int i = 0; i < fds_count; i++) {
> > +			if (!uatomic_set_true(&entry->fds[i].in_use))
> > +				/* failed to grab, someone is using */
> > +				continue;
> > +
> > +			if (entry->fds[i].fd == -1) {
> > +				/* this fd is not used */
> > +				uatomic_set_false(&entry->fds[i].in_use);
> > +				continue;
> > +			}
> > +
> > +			sd_debug("victim node: %s, fd: %d",
> > +				 nid_to_str(&entry->nid), entry->fds[i].fd);
> > +			close(entry->fds[i].fd);
> > +			entry->fds[i].fd = -1;
> > +			uatomic_set_false(&entry->fds[i].in_use);
> > +
> > +			shrink_head = rb_next(p);
> > +
> > +			ret = true;
> > +			goto out;
> > +		}
> > +
> > +		p = rb_next(p);
> > +		if (!p)
> > +			p = rb_first(&sockfd_cache.root);
> > +	} while (first != p);
> > +
> > +	sd_debug("shrinking couldn't be done");
> > +
> > +out:
> > +	sd_unlock(&sockfd_cache.lock);
> > +	return ret;
> > +}
> 
> Use for(entry = rb_first; entry; entry = rb_next) look cleaner for iteration

OK, I'll rewrite the loop in the next version.

Thanks,
Hitoshi



More information about the sheepdog mailing list