diff --git a/qdisc.c b/qdisc.c index 5f8e664..3061c44 100644 --- a/qdisc.c +++ b/qdisc.c @@ -272,11 +272,21 @@ static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct gnet_dump *d) { struct netdev_queue *dev_queue = mq_queue_get(sch, cl); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) + struct gnet_stats_basic_cpu __percpu *cpu_bstats = NULL; + struct gnet_stats_queue __percpu *cpu_qstats = NULL; + __u32 qlen; +#endif sch = dev_queue->qdisc_sleeping; sch->qstats.qlen = sch->q.qlen; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) if (gnet_stats_copy_basic(d, &sch->bstats) < 0 || gnet_stats_copy_queue(d, &sch->qstats) < 0) +#else + qlen = sch->q.qlen; + if (gnet_stats_copy_basic(d, cpu_bstats, &sch->bstats) < 0 || + gnet_stats_copy_queue(d, cpu_qstats, &sch->qstats, qlen) < 0) +#endif return -1; return 0; } diff --git a/stats.c b/stats.c index 684e649..713b6a1 100644 --- a/stats.c +++ b/stats.c @@ -37,7 +37,9 @@ static void iso_stats_proc_seq_stop(struct seq_file *s, void *v) static int iso_stats_proc_seq_show(struct seq_file *s, void *v) { struct hlist_head *head; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) struct hlist_node *node; +#endif struct iso_tx_class *txc; struct iso_vq *vq, *vq_next; struct iso_tx_context *txctx, *txctx_next; @@ -50,7 +52,11 @@ static int iso_stats_proc_seq_show(struct seq_file *s, void *v) for(i = 0; i < ISO_MAX_TX_BUCKETS; i++) { head = &txctx->iso_tx_bucket[i]; - hlist_for_each_entry_rcu(txc, node, head, hash_node) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) + hlist_for_each_entry_rcu(txc, node, head, hash_node) { +#else + hlist_for_each_entry_rcu(txc, head, hash_node) { +#endif iso_txc_show(txc, s); } } @@ -107,7 +113,9 @@ static int iso_csvstats_proc_seq_show(struct seq_file *s, void *v) { return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) static struct proc_dir_entry *iso_stats_proc; +#endif static struct seq_operations iso_stats_proc_seq_ops = { .start = iso_stats_proc_seq_start, @@ -131,7 +139,9 @@ static struct file_operations iso_stats_proc_file_ops = { /* For program friendly CSV stats */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) static struct proc_dir_entry *iso_csvstats_proc; +#endif static struct seq_operations iso_csvstats_proc_seq_ops = { .start = iso_stats_proc_seq_start, @@ -157,6 +167,7 @@ static struct file_operations iso_csvstats_proc_file_ops = { int iso_stats_init() { int ret = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) iso_stats_proc = create_proc_entry(ISO_STATS_PROC_NAME, 0, NULL); if(iso_stats_proc) { iso_stats_proc->proc_fops = &iso_stats_proc_file_ops; @@ -164,7 +175,6 @@ int iso_stats_init() { ret = 1; goto out; } - iso_csvstats_proc = create_proc_entry(ISO_CSVSTATS_PROC_NAME, 0, NULL); if(iso_csvstats_proc) { iso_csvstats_proc->proc_fops = &iso_csvstats_proc_file_ops; @@ -173,8 +183,15 @@ int iso_stats_init() { remove_proc_entry(ISO_STATS_PROC_NAME, NULL); goto out; } - - out: +#else + proc_create(ISO_STATS_PROC_NAME, 0, NULL, &iso_stats_proc_file_ops); + proc_create(ISO_CSVSTATS_PROC_NAME, 0, NULL, &iso_csvstats_proc_file_ops); +#endif + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) +out: +#endif return ret; } diff --git a/tx.c b/tx.c index ae0d094..94c3e99 100644 --- a/tx.c +++ b/tx.c @@ -1,6 +1,7 @@ #include #include +#include #include "tx.h" #include "vq.h" @@ -57,7 +58,10 @@ int iso_tx_init(struct iso_tx_context *context) { void iso_tx_exit(struct iso_tx_context *context) { int i; struct hlist_head *head; - struct hlist_node *node, *nextnode; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) + struct *nextnode; +#endif + struct hlist_node *node; struct iso_tx_class *txc; iso_rl_exit(context->rlcb); @@ -66,7 +70,11 @@ void iso_tx_exit(struct iso_tx_context *context) { for(i = 0; i < ISO_MAX_TX_BUCKETS; i++) { head = &context->iso_tx_bucket[i]; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_safe(txc, nextnode, node, head, hash_node) { +#else + hlist_for_each_entry_safe(txc, node, head, hash_node) { +#endif hlist_del(&txc->hash_node); iso_txc_free(txc); } @@ -143,7 +151,9 @@ inline void iso_txc_tick(struct iso_tx_context *context) { /* Called with rcu lock */ void iso_txc_show(struct iso_tx_class *txc, struct seq_file *s) { int i, nth; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) struct hlist_node *node; +#endif struct hlist_head *head; struct iso_rl *rl; struct iso_per_dest_state *state; @@ -171,7 +181,11 @@ void iso_txc_show(struct iso_tx_class *txc, struct seq_file *s) { seq_printf(s, "per dest state:\n"); for(i = 0; i < ISO_MAX_STATE_BUCKETS; i++) { head = &txc->state_bucket[i]; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_rcu(state, node, head, hash_node) { +#else + hlist_for_each_entry_rcu(state, head, hash_node) { +#endif seq_printf(s, "ip %x rl %p hash %d\n", state->ip_key, state->rl, i); iso_rc_show(&state->tx_rc, s); } @@ -182,8 +196,11 @@ void iso_txc_show(struct iso_tx_class *txc, struct seq_file *s) { for(i = 0; i < ISO_MAX_RL_BUCKETS; i++) { head = &txc->rl_bucket[i]; nth = 0; - +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_rcu(rl, node, head, hash_node) { +#else + hlist_for_each_entry_rcu(rl, head, hash_node) { +#endif if(nth == 0) { seq_printf(s, "hash %d ", i); } @@ -243,8 +260,9 @@ struct iso_per_dest_state struct iphdr *iph; struct iso_per_dest_state *state = NULL, *nextstate; struct hlist_head *head; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) struct hlist_node *node; - +#endif u32 ip, hash; eth = eth_hdr(skb); @@ -264,7 +282,11 @@ struct iso_per_dest_state head = &txc->state_bucket[hash]; state = NULL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_rcu(state, node, head, hash_node) { +#else + hlist_for_each_entry_rcu(state, head, hash_node) { +#endif if(state->ip_key == ip) break; } @@ -276,14 +298,17 @@ struct iso_per_dest_state return NULL; /* Check again; shouldn't we use a rwlock_t? */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_rcu(state, node, head, hash_node) { +#else + hlist_for_each_entry_rcu(state, head, hash_node) { +#endif if(state->ip_key == ip) break; } if(unlikely(state != NULL)) goto unlock; - list_for_each_entry_safe(state, nextstate, &txc->prealloc_state_list, prealloc_list) { state->ip_key = ip; state->rl = iso_pick_rl(txc, ip); @@ -318,11 +343,17 @@ void iso_state_free(struct iso_per_dest_state *state) { struct iso_rl *iso_pick_rl(struct iso_tx_class *txc, __le32 ip) { struct iso_rl *rl = NULL, *temp; struct hlist_head *head; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) struct hlist_node *node; +#endif rcu_read_lock(); head = &txc->rl_bucket[jhash_1word(ip, 0xfaceface) & (ISO_MAX_RL_BUCKETS - 1)]; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_rcu(rl, node, head, hash_node) { +#else + hlist_for_each_entry_rcu(rl, head, hash_node) { +#endif if(rl->ip == ip) goto found; } @@ -453,7 +484,10 @@ void iso_txc_prealloc(struct iso_tx_class *txc, int num) { /* Called with rcu lock */ void iso_txc_free(struct iso_tx_class *txc) { struct hlist_head *head; - struct hlist_node *n, *nn; + struct hlist_node *n; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) + struct hlist_node *nn; +#endif struct iso_rl *rl, *temprl; struct iso_per_dest_state *state, *tempstate; int i; @@ -463,7 +497,11 @@ void iso_txc_free(struct iso_tx_class *txc) { /* Kill each rate limiter */ for(i = 0; i < ISO_MAX_RL_BUCKETS; i++) { head = &txc->rl_bucket[i]; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_safe(rl, n, nn, head, hash_node) { +#else + hlist_for_each_entry_safe(rl, n, head, hash_node) { +#endif hlist_del_init_rcu(&rl->hash_node); iso_rl_free(rl); } @@ -472,7 +510,11 @@ void iso_txc_free(struct iso_tx_class *txc) { /* Kill each state */ for(i = 0; i < ISO_MAX_STATE_BUCKETS; i++) { head = &txc->state_bucket[i]; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_safe(state, n, nn, head, hash_node) { +#else + hlist_for_each_entry_safe(state, n, head, hash_node) { +#endif hlist_del_init_rcu(&state->hash_node); iso_state_free(state); } diff --git a/tx.h b/tx.h index e373e26..0486fa9 100644 --- a/tx.h +++ b/tx.h @@ -139,10 +139,15 @@ static inline struct iso_tx_class *iso_txc_find(iso_class_t klass, struct iso_tx struct hlist_head *head = iso_txc_find_bucket(klass, context); struct iso_tx_class *txc; struct iso_tx_class *found = NULL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) struct hlist_node *n; - +#endif rcu_read_lock(); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) hlist_for_each_entry_rcu(txc, n, head, hash_node) { +#else + hlist_for_each_entry_rcu(txc, head, hash_node) { +#endif if(iso_class_cmp(txc->klass, klass) == 0) { found = txc; break; diff --git a/vq.h b/vq.h index a9a2b3a..c1821b3 100644 --- a/vq.h +++ b/vq.h @@ -102,10 +102,13 @@ void iso_vq_show(struct iso_vq *, struct seq_file *); static inline struct iso_vq *iso_vq_find(iso_class_t klass, struct iso_rx_context *rxctx) { u32 hash = iso_class_hash(klass); struct hlist_head *head = &rxctx->vq_bucket[hash & (ISO_MAX_VQ_BUCKETS - 1)]; - struct hlist_node *node; struct iso_vq *vq; - +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) + struct hlist_node *node; hlist_for_each_entry_rcu(vq, node, head, hash_node) { +#else + hlist_for_each_entry_rcu(vq, head, hash_node) { +#endif if(iso_class_cmp(vq->klass, klass) == 0) return vq; }