All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>
Cc: rusty@rustcorp.com.au, netfilter-devel@lists.netfilter.org,
	pablo@netfilter.org, kadlec@blackhole.kfki.hu
Subject: Re: [PATCH 02/10] nf_conntrack: Introduces a extension infrastructure
Date: Mon, 25 Jun 2007 12:01:02 +0200	[thread overview]
Message-ID: <467F925E.7090703@trash.net> (raw)
In-Reply-To: <200706250314.l5P3EeGY021239@toshiba.co.jp>

Yasuyuki KOZAKAI wrote:
> +static void *
> +nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, int gfp)
> +{
> +	unsigned int off, len, real_len;
> +	struct nf_ct_ext_type *t;
> +
> +	rcu_read_lock();
> +	t = rcu_dereference(nf_ct_ext_types[id]);
> +	BUG_ON(t == NULL);
> +	off = ALIGN(sizeof(struct nf_ct_ext), t->align);
> +	len = off + t->len;
> +	real_len = t->alloc_size;
> +	rcu_read_unlock();
> +
> +	*ext = kmalloc(real_len, gfp);
> +	if (!*ext)
> +		return NULL;
> +
> +	memset(*ext, 0, len);

Minor improvement: you could use kzalloc above

> +
> +	(*ext)->offset[id] = off;
> +	(*ext)->len = len;
> +	(*ext)->real_len = real_len;
> +
> +	return (void *)(*ext) + off;
> +}
> +
> +void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, int gfp)


Does any caller actually use something besides GFP_ATOMIC for gfp?

> +{
> +	struct nf_ct_ext *new;
> +	int i, newlen, newoff;
> +	struct nf_ct_ext_type *t;
> +
> +	if (!ct->ext)
> +		return nf_ct_ext_create(&ct->ext, id, gfp);
> +
> +	if (nf_ct_ext_exist(ct, id))
> +		return NULL;
> +
> +	rcu_read_lock();
> +	t = rcu_dereference(nf_ct_ext_types[id]);
> +	BUG_ON(t == NULL);
> +
> +	newoff = ALIGN(ct->ext->len, t->align);
> +	newlen = newoff + t->len;
> +	rcu_read_unlock();
> +
> +	if (newlen >= ct->ext->real_len) {
> +		new = kmalloc(newlen, gfp);
> +		if (!new)
> +			return NULL;
> +
> +		memcpy(new, ct->ext, ct->ext->len);

And maybe krealloc here?

> +
> +		for (i = 0; i < NF_CT_EXT_MAX; i++) {
> +			if (!nf_ct_ext_exist(ct, i))
> +				continue;
> +
> +			rcu_read_lock();
> +			t = rcu_dereference(nf_ct_ext_types[i]);
> +			if (t && t->move)
> +				t->move(ct, ct->ext + ct->ext->offset[id]);
> +			rcu_read_unlock();
> +		}
> +		kfree(ct->ext);
> +		new->real_len = newlen;
> +		ct->ext = new;
> +	}
> +
> +	ct->ext->offset[id] = newoff;
> +	ct->ext->len = newlen;
> +	memset((void *)ct->ext + newoff, 0, newlen - newoff);
> +	return (void *)ct->ext + newoff;
> +}
> +EXPORT_SYMBOL(__nf_ct_ext_add);
> +
> +static void update_alloc_size(enum nf_ct_ext_id id)
> +{
> +	int i, j;
> +	struct nf_ct_ext_type *t1, *t2;
> +	enum nf_ct_ext_id min = 0, max = NF_CT_EXT_MAX - 1;
> +
> +	/* unnecessary to update all types */
> +	if ((nf_ct_ext_types[id]->flags & NF_CT_EXT_F_PREALLOC) == 0) {
> +		min = id;
> +		max = id;
> +	}
> +
> +	/* This assumes that extended areas in conntrack for the types
> +  	   whose NF_CT_EXT_F_PREALLOC bit set are allocated in order */
> +	for (i = min; i <= max; i++) {
> +		t1 = nf_ct_ext_types[i];
> +		if (!t1)
> +			continue;
> +
> +		t1->alloc_size = sizeof(struct nf_ct_ext)
> +				 + ALIGN(sizeof(struct nf_ct_ext), t1->align)
> +				 + t1->len;
> +		for (j = 0; j < NF_CT_EXT_MAX; j++) {
> +			t2 = nf_ct_ext_types[j];
> +			if (t2 == NULL || t2 == t1 ||
> +			    (t2->flags & NF_CT_EXT_F_PREALLOC) == 0)
> +				continue;
> +
> +			t1->alloc_size = ALIGN(t1->alloc_size, t2->align)
> +					 + t2->len;
> +		}
> +		if (t1->alloc_size < NF_CT_EXT_MIN_SIZE)
> +			t1->alloc_size = NF_CT_EXT_MIN_SIZE;
> +	}
> +}
> +
> +/* This MUST be called in process context. */
> +int nf_ct_extend_register(struct nf_ct_ext_type *type)
> +{
> +	int ret = 0;
> +
> +	mutex_lock(&nf_ct_ext_type_mutex);
> +	if (nf_ct_ext_types[type->id]) {
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +
> +	/* This ensures that nf_ct_ext_create() can allocate enough area
> +	   before updating alloc_size */
> +	type->alloc_size = ALIGN(sizeof(struct nf_ct_ext), type->align)
> +			   + type->len;
> +	rcu_assign_pointer(nf_ct_ext_types[type->id], type);
> +	update_alloc_size(type->id);
> +out:
> +	mutex_unlock(&nf_ct_ext_type_mutex);
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(nf_ct_extend_register);
> +
> +/* This MUST be called in process context. */
> +void nf_ct_extend_unregister(struct nf_ct_ext_type *type)
> +{
> +	mutex_lock(&nf_ct_ext_type_mutex);
> +	rcu_assign_pointer(nf_ct_ext_types[type->id], NULL);


This seems to need synchronize_rcu().

> +	update_alloc_size(type->id);
> +	mutex_unlock(&nf_ct_ext_type_mutex);
> +}
> +EXPORT_SYMBOL_GPL(nf_ct_extend_unregister);

  reply	other threads:[~2007-06-25 10:01 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-25  3:14 [PATCH 02/10] nf_conntrack: Introduces a extension infrastructure Yasuyuki KOZAKAI
2007-06-25 10:01 ` Patrick McHardy [this message]
2007-06-25 15:35   ` Yasuyuki KOZAKAI
2007-06-25 15:43     ` Patrick McHardy
  -- strict thread matches above, loose matches on Subject: below --
2007-06-25 17:21 Yasuyuki KOZAKAI
     [not found] <200706251721.l5PHLQ8x023174@toshiba.co.jp>
2007-06-25 18:16 ` Patrick McHardy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=467F925E.7090703@trash.net \
    --to=kaber@trash.net \
    --cc=kadlec@blackhole.kfki.hu \
    --cc=netfilter-devel@lists.netfilter.org \
    --cc=pablo@netfilter.org \
    --cc=rusty@rustcorp.com.au \
    --cc=yasuyuki.kozakai@toshiba.co.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.