All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vlad Yasevich <vladislav.yasevich@hp.com>
To: Yaogong Wang <ywang15@ncsu.edu>
Cc: linux-sctp@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCHv2 2/5] sctp: implement pluggable multistream scheduling
Date: Mon, 13 Sep 2010 13:45:06 +0000	[thread overview]
Message-ID: <4C8E2AE2.9050309@hp.com> (raw)
In-Reply-To: <AANLkTinaO5Fqn+QJxxkXSCsW0XWvhBc16jK6HGB_0YG0@mail.gmail.com>

One small nit.

On 09/11/2010 09:12 PM, Yaogong Wang wrote:
> Implement the pluggable multistream scheduling framework.
> Provide the default first-come-first-serve (FCFS) algorithm.
> 
> Signed-off-by: Yaogong Wang <ywang15@ncsu.edu>
> ---
> diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
> index 5027b83..d40c5cc 100644
> --- a/net/sctp/protocol.c
> +++ b/net/sctp/protocol.c
> @@ -1157,6 +1157,9 @@ SCTP_STATIC __init int sctp_init(void)
>  	sctp_max_instreams    		= SCTP_DEFAULT_INSTREAMS;
>  	sctp_max_outstreams   		= SCTP_DEFAULT_OUTSTREAMS;
> 
> +	/* Initialize default multistream scheduling algorithm to FCFS */
> +	sctp_default_sched_ops		= &sctp_fcfs;
> +
>  	/* Initialize handle used for association ids. */
>  	idr_init(&sctp_assocs_id);
> 
> @@ -1304,6 +1307,11 @@ SCTP_STATIC __init int sctp_init(void)
>  	if (status)
>  		goto err_v6_add_protocol;
> 
> +	/* Add FCFS to sctp_sched_list */
> +	status = sctp_register_sched(&sctp_fcfs);
> +	if (status)
> +		goto err_v6_add_protocol;
> +

This needs its own tag that will call sctp_v6_del_protocol().

-vlad

>  	status = 0;
>  out:
>  	return status;
> @@ -1348,6 +1356,9 @@ SCTP_STATIC __exit void sctp_exit(void)
>  	 * up all the remaining associations and all that memory.
>  	 */
> 
> +	/* Unregister FCFS from sctp_sched_list */
> +	sctp_unregister_sched(&sctp_fcfs);
> +
>  	/* Unregister with inet6/inet layers. */
>  	sctp_v6_del_protocol();
>  	sctp_v4_del_protocol();
> diff --git a/net/sctp/sched.c b/net/sctp/sched.c
> new file mode 100644
> index 0000000..3820e3f
> --- /dev/null
> +++ b/net/sctp/sched.c
> @@ -0,0 +1,177 @@
> +/*
> + * Plugable SCTP multistream scheduling support and
> + * the default first-come-first-serve (FCFS) algorithm
> + *
> + * Based on ideas from pluggable TCP congestion control
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/list.h>
> +#include <net/sctp/sctp.h>
> +
> +static DEFINE_SPINLOCK(sctp_sched_list_lock);
> +static LIST_HEAD(sctp_sched_list);
> +
> +/* Simple linear search, don't expect many entries! */
> +static struct sctp_sched_ops *sctp_sched_find(const char *name)
> +{
> +	struct sctp_sched_ops *e;
> +
> +	list_for_each_entry_rcu(e, &sctp_sched_list, list) {
> +		if (strcmp(e->name, name) = 0)
> +			return e;
> +	}
> +
> +	return NULL;
> +}
> +
> +/*
> + * Attach new scheduling algorithm to the list
> + * of available options.
> + */
> +int sctp_register_sched(struct sctp_sched_ops *sched)
> +{
> +	int ret = 0;
> +
> +	/* algorithm must implement required ops */
> +	if (!sched->init || !sched->release || !sched->is_empty
> +		|| !sched->enqueue_head_data || !sched->enqueue_tail_data
> +		|| !sched->dequeue_data) {
> +		printk(KERN_ERR "SCTP %s does not implement required ops\n",
> +		       sched->name);
> +		return -EINVAL;
> +	}
> +
> +	spin_lock(&sctp_sched_list_lock);
> +	if (sctp_sched_find(sched->name)) {
> +		printk(KERN_NOTICE "SCTP %s already registered\n", sched->name);
> +		ret = -EEXIST;
> +	} else {
> +		list_add_tail_rcu(&sched->list, &sctp_sched_list);
> +		printk(KERN_INFO "SCTP %s registered\n", sched->name);
> +	}
> +	spin_unlock(&sctp_sched_list_lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(sctp_register_sched);
> +
> +/*
> + * Remove scheduling algorithm, called from
> + * the module's remove function.  Module ref counts are used
> + * to ensure that this can't be done till all sockets using
> + * that method are closed.
> + */
> +void sctp_unregister_sched(struct sctp_sched_ops *sched)
> +{
> +	spin_lock(&sctp_sched_list_lock);
> +	list_del_rcu(&sched->list);
> +	spin_unlock(&sctp_sched_list_lock);
> +}
> +EXPORT_SYMBOL_GPL(sctp_unregister_sched);
> +
> +/* Manage refcounts on socket close. */
> +void sctp_cleanup_sched(struct sock *sk)
> +{
> +	module_put(sctp_sk(sk)->sched_ops->owner);
> +}
> +
> +/* Change scheduling algorithm for socket */
> +int sctp_set_sched(struct sock *sk, const char *name)
> +{
> +	struct sctp_sock *sp = sctp_sk(sk);
> +	struct sctp_sched_ops *sched;
> +	int err = 0;
> +
> +	rcu_read_lock();
> +	sched = sctp_sched_find(name);
> +
> +	/* no change asking for existing value */
> +	if (sched = sp->sched_ops)
> +		goto out;
> +
> +#ifdef CONFIG_MODULES
> +	/* not found attempt to autoload module */
> +	if (!sched && capable(CAP_NET_ADMIN)) {
> +		rcu_read_unlock();
> +		request_module("sctp_%s", name);
> +		rcu_read_lock();
> +		sched = sctp_sched_find(name);
> +	}
> +#endif
> +	if (!sched)
> +		err = -ENOENT;
> +
> +	else if (!try_module_get(sched->owner))
> +		err = -EBUSY;
> +
> +	else {
> +		sctp_cleanup_sched(sk);
> +		sp->sched_ops = sched;
> +	}
> +out:
> +	rcu_read_unlock();
> +	return err;
> +}
> +
> +static int fcfs_init(struct sctp_outq *q, gfp_t gfp)
> +{
> +	q->out_chunk_list = kmalloc(sizeof(struct list_head), gfp);
> +	if (!q->out_chunk_list)
> +		return -ENOMEM;
> +	INIT_LIST_HEAD(q->out_chunk_list);
> +
> +	return 0;
> +}
> +
> +static void fcfs_release(struct sctp_outq *q)
> +{
> +	kfree(q->out_chunk_list);
> +}
> +
> +static void fcfs_enqueue_head_data(struct sctp_outq *q,
> +					struct sctp_chunk *ch)
> +{
> +	list_add(&ch->list, q->out_chunk_list);
> +	q->out_qlen += ch->skb->len;
> +	return;
> +}
> +
> +static void fcfs_enqueue_tail_data(struct sctp_outq *q, struct sctp_chunk *ch)
> +{
> +	list_add_tail(&ch->list, q->out_chunk_list);
> +	q->out_qlen += ch->skb->len;
> +	return;
> +}
> +
> +static struct sctp_chunk *fcfs_dequeue_data(struct sctp_outq *q)
> +{
> +	struct sctp_chunk *ch = NULL;
> +
> +	if (!list_empty(q->out_chunk_list)) {
> +		struct list_head *entry = q->out_chunk_list->next;
> +
> +		ch = list_entry(entry, struct sctp_chunk, list);
> +		list_del_init(entry);
> +		q->out_qlen -= ch->skb->len;
> +	}
> +	return ch;
> +}
> +
> +static inline int fcfs_is_empty(struct sctp_outq *q)
> +{
> +	return list_empty(q->out_chunk_list);
> +}
> +
> +struct sctp_sched_ops sctp_fcfs = {
> +	.name			= "fcfs",
> +	.owner			= THIS_MODULE,
> +	.init			= fcfs_init,
> +	.release		= fcfs_release,
> +	.enqueue_head_data	= fcfs_enqueue_head_data,
> +	.enqueue_tail_data	= fcfs_enqueue_tail_data,
> +	.dequeue_data		= fcfs_dequeue_data,
> +	.is_empty		= fcfs_is_empty,
> +};
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index ca44917..7d461be 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -3644,6 +3644,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
>  	sp->initmsg.sinit_max_attempts   = sctp_max_retrans_init;
>  	sp->initmsg.sinit_max_init_timeo = sctp_rto_max;
> 
> +	/* Initialize default multistream scheduling algorithm */
> +	sp->sched_ops = sctp_default_sched_ops;
> +
>  	/* Initialize default RTO related parameters.  These parameters can
>  	 * be modified for with the SCTP_RTOINFO socket option.
>  	 */


WARNING: multiple messages have this Message-ID (diff)
From: Vlad Yasevich <vladislav.yasevich@hp.com>
To: Yaogong Wang <ywang15@ncsu.edu>
Cc: linux-sctp@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCHv2 2/5] sctp: implement pluggable multistream scheduling
Date: Mon, 13 Sep 2010 09:45:06 -0400	[thread overview]
Message-ID: <4C8E2AE2.9050309@hp.com> (raw)
In-Reply-To: <AANLkTinaO5Fqn+QJxxkXSCsW0XWvhBc16jK6HGB_0YG0@mail.gmail.com>

One small nit.

On 09/11/2010 09:12 PM, Yaogong Wang wrote:
> Implement the pluggable multistream scheduling framework.
> Provide the default first-come-first-serve (FCFS) algorithm.
> 
> Signed-off-by: Yaogong Wang <ywang15@ncsu.edu>
> ---
> diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
> index 5027b83..d40c5cc 100644
> --- a/net/sctp/protocol.c
> +++ b/net/sctp/protocol.c
> @@ -1157,6 +1157,9 @@ SCTP_STATIC __init int sctp_init(void)
>  	sctp_max_instreams    		= SCTP_DEFAULT_INSTREAMS;
>  	sctp_max_outstreams   		= SCTP_DEFAULT_OUTSTREAMS;
> 
> +	/* Initialize default multistream scheduling algorithm to FCFS */
> +	sctp_default_sched_ops		= &sctp_fcfs;
> +
>  	/* Initialize handle used for association ids. */
>  	idr_init(&sctp_assocs_id);
> 
> @@ -1304,6 +1307,11 @@ SCTP_STATIC __init int sctp_init(void)
>  	if (status)
>  		goto err_v6_add_protocol;
> 
> +	/* Add FCFS to sctp_sched_list */
> +	status = sctp_register_sched(&sctp_fcfs);
> +	if (status)
> +		goto err_v6_add_protocol;
> +

This needs its own tag that will call sctp_v6_del_protocol().

-vlad

>  	status = 0;
>  out:
>  	return status;
> @@ -1348,6 +1356,9 @@ SCTP_STATIC __exit void sctp_exit(void)
>  	 * up all the remaining associations and all that memory.
>  	 */
> 
> +	/* Unregister FCFS from sctp_sched_list */
> +	sctp_unregister_sched(&sctp_fcfs);
> +
>  	/* Unregister with inet6/inet layers. */
>  	sctp_v6_del_protocol();
>  	sctp_v4_del_protocol();
> diff --git a/net/sctp/sched.c b/net/sctp/sched.c
> new file mode 100644
> index 0000000..3820e3f
> --- /dev/null
> +++ b/net/sctp/sched.c
> @@ -0,0 +1,177 @@
> +/*
> + * Plugable SCTP multistream scheduling support and
> + * the default first-come-first-serve (FCFS) algorithm
> + *
> + * Based on ideas from pluggable TCP congestion control
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/list.h>
> +#include <net/sctp/sctp.h>
> +
> +static DEFINE_SPINLOCK(sctp_sched_list_lock);
> +static LIST_HEAD(sctp_sched_list);
> +
> +/* Simple linear search, don't expect many entries! */
> +static struct sctp_sched_ops *sctp_sched_find(const char *name)
> +{
> +	struct sctp_sched_ops *e;
> +
> +	list_for_each_entry_rcu(e, &sctp_sched_list, list) {
> +		if (strcmp(e->name, name) == 0)
> +			return e;
> +	}
> +
> +	return NULL;
> +}
> +
> +/*
> + * Attach new scheduling algorithm to the list
> + * of available options.
> + */
> +int sctp_register_sched(struct sctp_sched_ops *sched)
> +{
> +	int ret = 0;
> +
> +	/* algorithm must implement required ops */
> +	if (!sched->init || !sched->release || !sched->is_empty
> +		|| !sched->enqueue_head_data || !sched->enqueue_tail_data
> +		|| !sched->dequeue_data) {
> +		printk(KERN_ERR "SCTP %s does not implement required ops\n",
> +		       sched->name);
> +		return -EINVAL;
> +	}
> +
> +	spin_lock(&sctp_sched_list_lock);
> +	if (sctp_sched_find(sched->name)) {
> +		printk(KERN_NOTICE "SCTP %s already registered\n", sched->name);
> +		ret = -EEXIST;
> +	} else {
> +		list_add_tail_rcu(&sched->list, &sctp_sched_list);
> +		printk(KERN_INFO "SCTP %s registered\n", sched->name);
> +	}
> +	spin_unlock(&sctp_sched_list_lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(sctp_register_sched);
> +
> +/*
> + * Remove scheduling algorithm, called from
> + * the module's remove function.  Module ref counts are used
> + * to ensure that this can't be done till all sockets using
> + * that method are closed.
> + */
> +void sctp_unregister_sched(struct sctp_sched_ops *sched)
> +{
> +	spin_lock(&sctp_sched_list_lock);
> +	list_del_rcu(&sched->list);
> +	spin_unlock(&sctp_sched_list_lock);
> +}
> +EXPORT_SYMBOL_GPL(sctp_unregister_sched);
> +
> +/* Manage refcounts on socket close. */
> +void sctp_cleanup_sched(struct sock *sk)
> +{
> +	module_put(sctp_sk(sk)->sched_ops->owner);
> +}
> +
> +/* Change scheduling algorithm for socket */
> +int sctp_set_sched(struct sock *sk, const char *name)
> +{
> +	struct sctp_sock *sp = sctp_sk(sk);
> +	struct sctp_sched_ops *sched;
> +	int err = 0;
> +
> +	rcu_read_lock();
> +	sched = sctp_sched_find(name);
> +
> +	/* no change asking for existing value */
> +	if (sched == sp->sched_ops)
> +		goto out;
> +
> +#ifdef CONFIG_MODULES
> +	/* not found attempt to autoload module */
> +	if (!sched && capable(CAP_NET_ADMIN)) {
> +		rcu_read_unlock();
> +		request_module("sctp_%s", name);
> +		rcu_read_lock();
> +		sched = sctp_sched_find(name);
> +	}
> +#endif
> +	if (!sched)
> +		err = -ENOENT;
> +
> +	else if (!try_module_get(sched->owner))
> +		err = -EBUSY;
> +
> +	else {
> +		sctp_cleanup_sched(sk);
> +		sp->sched_ops = sched;
> +	}
> +out:
> +	rcu_read_unlock();
> +	return err;
> +}
> +
> +static int fcfs_init(struct sctp_outq *q, gfp_t gfp)
> +{
> +	q->out_chunk_list = kmalloc(sizeof(struct list_head), gfp);
> +	if (!q->out_chunk_list)
> +		return -ENOMEM;
> +	INIT_LIST_HEAD(q->out_chunk_list);
> +
> +	return 0;
> +}
> +
> +static void fcfs_release(struct sctp_outq *q)
> +{
> +	kfree(q->out_chunk_list);
> +}
> +
> +static void fcfs_enqueue_head_data(struct sctp_outq *q,
> +					struct sctp_chunk *ch)
> +{
> +	list_add(&ch->list, q->out_chunk_list);
> +	q->out_qlen += ch->skb->len;
> +	return;
> +}
> +
> +static void fcfs_enqueue_tail_data(struct sctp_outq *q, struct sctp_chunk *ch)
> +{
> +	list_add_tail(&ch->list, q->out_chunk_list);
> +	q->out_qlen += ch->skb->len;
> +	return;
> +}
> +
> +static struct sctp_chunk *fcfs_dequeue_data(struct sctp_outq *q)
> +{
> +	struct sctp_chunk *ch = NULL;
> +
> +	if (!list_empty(q->out_chunk_list)) {
> +		struct list_head *entry = q->out_chunk_list->next;
> +
> +		ch = list_entry(entry, struct sctp_chunk, list);
> +		list_del_init(entry);
> +		q->out_qlen -= ch->skb->len;
> +	}
> +	return ch;
> +}
> +
> +static inline int fcfs_is_empty(struct sctp_outq *q)
> +{
> +	return list_empty(q->out_chunk_list);
> +}
> +
> +struct sctp_sched_ops sctp_fcfs = {
> +	.name			= "fcfs",
> +	.owner			= THIS_MODULE,
> +	.init			= fcfs_init,
> +	.release		= fcfs_release,
> +	.enqueue_head_data	= fcfs_enqueue_head_data,
> +	.enqueue_tail_data	= fcfs_enqueue_tail_data,
> +	.dequeue_data		= fcfs_dequeue_data,
> +	.is_empty		= fcfs_is_empty,
> +};
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index ca44917..7d461be 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -3644,6 +3644,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
>  	sp->initmsg.sinit_max_attempts   = sctp_max_retrans_init;
>  	sp->initmsg.sinit_max_init_timeo = sctp_rto_max;
> 
> +	/* Initialize default multistream scheduling algorithm */
> +	sp->sched_ops = sctp_default_sched_ops;
> +
>  	/* Initialize default RTO related parameters.  These parameters can
>  	 * be modified for with the SCTP_RTOINFO socket option.
>  	 */


  reply	other threads:[~2010-09-13 13:45 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-12  1:12 [PATCHv2 2/5] sctp: implement pluggable multistream scheduling Yaogong Wang
2010-09-12  1:12 ` Yaogong Wang
2010-09-13 13:45 ` Vlad Yasevich [this message]
2010-09-13 13:45   ` Vlad Yasevich
2010-09-19 18:56   ` Yaogong Wang
2010-09-19 18:56     ` Yaogong Wang

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=4C8E2AE2.9050309@hp.com \
    --to=vladislav.yasevich@hp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sctp@vger.kernel.org \
    --cc=ywang15@ncsu.edu \
    /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.