~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/sched/sch_fifo.c

Version: ~ [ linux-6.4-rc3 ] ~ [ linux-6.3.4 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.30 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.113 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.180 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.243 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.283 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.315 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * net/sched/sch_fifo.c The simplest FIFO queue.
  3  *
  4  *              This program is free software; you can redistribute it and/or
  5  *              modify it under the terms of the GNU General Public License
  6  *              as published by the Free Software Foundation; either version
  7  *              2 of the License, or (at your option) any later version.
  8  *
  9  * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 10  */
 11 
 12 #include <linux/config.h>
 13 #include <linux/module.h>
 14 #include <asm/uaccess.h>
 15 #include <asm/system.h>
 16 #include <asm/bitops.h>
 17 #include <linux/types.h>
 18 #include <linux/kernel.h>
 19 #include <linux/sched.h>
 20 #include <linux/string.h>
 21 #include <linux/mm.h>
 22 #include <linux/socket.h>
 23 #include <linux/sockios.h>
 24 #include <linux/in.h>
 25 #include <linux/errno.h>
 26 #include <linux/interrupt.h>
 27 #include <linux/if_ether.h>
 28 #include <linux/inet.h>
 29 #include <linux/netdevice.h>
 30 #include <linux/etherdevice.h>
 31 #include <linux/notifier.h>
 32 #include <net/ip.h>
 33 #include <net/route.h>
 34 #include <linux/skbuff.h>
 35 #include <net/sock.h>
 36 #include <net/pkt_sched.h>
 37 
 38 /* 1 band FIFO pseudo-"scheduler" */
 39 
 40 struct fifo_sched_data
 41 {
 42         unsigned limit;
 43 };
 44 
 45 static int
 46 bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 47 {
 48         struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data;
 49 
 50         if (sch->stats.backlog + skb->len <= q->limit) {
 51                 __skb_queue_tail(&sch->q, skb);
 52                 sch->stats.backlog += skb->len;
 53                 sch->stats.bytes += skb->len;
 54                 sch->stats.packets++;
 55                 return 0;
 56         }
 57         sch->stats.drops++;
 58 #ifdef CONFIG_NET_CLS_POLICE
 59         if (sch->reshape_fail==NULL || sch->reshape_fail(skb, sch))
 60 #endif
 61                 kfree_skb(skb);
 62         return NET_XMIT_DROP;
 63 }
 64 
 65 static int
 66 bfifo_requeue(struct sk_buff *skb, struct Qdisc* sch)
 67 {
 68         __skb_queue_head(&sch->q, skb);
 69         sch->stats.backlog += skb->len;
 70         return 0;
 71 }
 72 
 73 static struct sk_buff *
 74 bfifo_dequeue(struct Qdisc* sch)
 75 {
 76         struct sk_buff *skb;
 77 
 78         skb = __skb_dequeue(&sch->q);
 79         if (skb)
 80                 sch->stats.backlog -= skb->len;
 81         return skb;
 82 }
 83 
 84 static unsigned int 
 85 fifo_drop(struct Qdisc* sch)
 86 {
 87         struct sk_buff *skb;
 88 
 89         skb = __skb_dequeue_tail(&sch->q);
 90         if (skb) {
 91                 unsigned int len = skb->len;
 92                 sch->stats.backlog -= len;
 93                 kfree_skb(skb);
 94                 return len;
 95         }
 96         return 0;
 97 }
 98 
 99 static void
100 fifo_reset(struct Qdisc* sch)
101 {
102         skb_queue_purge(&sch->q);
103         sch->stats.backlog = 0;
104 }
105 
106 static int
107 pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
108 {
109         struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data;
110 
111         if (sch->q.qlen < q->limit) {
112                 __skb_queue_tail(&sch->q, skb);
113                 sch->stats.bytes += skb->len;
114                 sch->stats.packets++;
115                 return 0;
116         }
117         sch->stats.drops++;
118 #ifdef CONFIG_NET_CLS_POLICE
119         if (sch->reshape_fail==NULL || sch->reshape_fail(skb, sch))
120 #endif
121                 kfree_skb(skb);
122         return NET_XMIT_DROP;
123 }
124 
125 static int
126 pfifo_requeue(struct sk_buff *skb, struct Qdisc* sch)
127 {
128         __skb_queue_head(&sch->q, skb);
129         return 0;
130 }
131 
132 
133 static struct sk_buff *
134 pfifo_dequeue(struct Qdisc* sch)
135 {
136         return __skb_dequeue(&sch->q);
137 }
138 
139 static int fifo_init(struct Qdisc *sch, struct rtattr *opt)
140 {
141         struct fifo_sched_data *q = (void*)sch->data;
142 
143         if (opt == NULL) {
144                 if (sch->ops == &bfifo_qdisc_ops)
145                         q->limit = sch->dev->tx_queue_len*sch->dev->mtu;
146                 else    
147                         q->limit = sch->dev->tx_queue_len;
148         } else {
149                 struct tc_fifo_qopt *ctl = RTA_DATA(opt);
150                 if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
151                         return -EINVAL;
152                 q->limit = ctl->limit;
153         }
154         return 0;
155 }
156 
157 static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
158 {
159         struct fifo_sched_data *q = (void*)sch->data;
160         unsigned char    *b = skb->tail;
161         struct tc_fifo_qopt opt;
162 
163         opt.limit = q->limit;
164         RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
165 
166         return skb->len;
167 
168 rtattr_failure:
169         skb_trim(skb, b - skb->data);
170         return -1;
171 }
172 
173 struct Qdisc_ops pfifo_qdisc_ops = {
174         .next           =       NULL,
175         .cl_ops         =       NULL,
176         .id             =       "pfifo",
177         .priv_size      =       sizeof(struct fifo_sched_data),
178         .enqueue        =       pfifo_enqueue,
179         .dequeue        =       pfifo_dequeue,
180         .requeue        =       pfifo_requeue,
181         .drop           =       fifo_drop,
182         .init           =       fifo_init,
183         .reset          =       fifo_reset,
184         .destroy        =       NULL,
185         .change         =       fifo_init,
186         .dump           =       fifo_dump,
187         .owner          =       THIS_MODULE,
188 };
189 
190 struct Qdisc_ops bfifo_qdisc_ops = {
191         .next           =       NULL,
192         .cl_ops         =       NULL,
193         .id             =       "bfifo",
194         .priv_size      =       sizeof(struct fifo_sched_data),
195         .enqueue        =       bfifo_enqueue,
196         .dequeue        =       bfifo_dequeue,
197         .requeue        =       bfifo_requeue,
198         .drop           =       fifo_drop,
199         .init           =       fifo_init,
200         .reset          =       fifo_reset,
201         .destroy        =       NULL,
202         .change         =       fifo_init,
203         .dump           =       fifo_dump,
204         .owner          =       THIS_MODULE,
205 };
206 
207 EXPORT_SYMBOL(bfifo_qdisc_ops);
208 EXPORT_SYMBOL(pfifo_qdisc_ops);
209 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp