bitkeeper revision 1.89 (3e58aeffGldVBDUrCPQ3AX0iBm4OYw)

Many files:
  Ripped out lots from code from Xen's network transmit path, pending a new scheduler.
devinit.c:
  Rename: xen-2.4.16/net/sch_generic.c -> xen-2.4.16/net/devinit.c
sch_generic.c:
  Rename: BitKeeper/deleted/.del-sch_generic.c~c8d7d9959cc80952 -> xen-2.4.16/net/sch_generic.c
.del-sch_generic.c~c8d7d9959cc80952:
  Delete: xen-2.4.16/net/sch_generic.c
.del-utils.c~e7553afc72d1b648:
  Delete: xen-2.4.16/net/utils.c
.del-pkt_sched.h~e13e384d6b974c61:
  Delete: xen-2.4.16/include/xeno/pkt_sched.h
This commit is contained in:
kaf24@labyrinth.cl.cam.ac.uk committed 2003-02-23 11:22:39 +00:00
1 parent ef170179d0
commit 0dc9ba5c3a
18 files changed
+1293 -2809

No files matched your search

+1 -3
View File
@@ -260,7 +260,6 @@
3ddb79c0MOVXq8qZDQRGb6z64_xAwg xen-2.4.16/include/xeno/pci_ids.h
3e54c38dlSCVdyVM4PKcrSfzLLxWUQ xen-2.4.16/include/xeno/perfc.h
3e54c38de9SUSYSAwxDf_DwkpAnQFA xen-2.4.16/include/xeno/perfc_defn.h
3ddb79c2byJwwNNkiES__A9H4Cvc4g xen-2.4.16/include/xeno/pkt_sched.h
3ddb79c04nQVR3EYM5L4zxDV_MCo1g xen-2.4.16/include/xeno/prefetch.h
3e4540ccU1sgCx8seIMGlahmMfv7yQ xen-2.4.16/include/xeno/reboot.h
3ddb79c0LzqqS0LhAQ50ekgj4oGl7Q xen-2.4.16/include/xeno/sched.h
@@ -279,10 +278,9 @@
3ddb79c4YQCQ6r0xNLLu0jfbM7pVmA xen-2.4.16/net/Makefile
3ddb79c4AkfDkTCw0comx4L8wsUOMg xen-2.4.16/net/dev.c
3ddb79c4x1L_soh8b-r_1jQW_37Icw xen-2.4.16/net/dev_mcast.c
3ddb79c4KZhNxUuYJ7lul8cc-wRkyg xen-2.4.16/net/devinit.c
3ddb79c4NSDwiQ-AmrYdxcRAwLPzwQ xen-2.4.16/net/eth.c
3ddb79c4KZhNxUuYJ7lul8cc-wRkyg xen-2.4.16/net/sch_generic.c
3ddb79c4TZj1wXPKQt36O72SddtBNQ xen-2.4.16/net/skbuff.c
3ddb79c4ARyIHqv3Y6YFckIUbyA8Tw xen-2.4.16/net/utils.c
3ddb79c4x8dvwPtzclghWAKFWpEBFA xen-2.4.16/tools/Makefile
3ddb79c4yGZ7_22QAFFwPzqP4NSHwA xen-2.4.16/tools/elf-reloc.c
3ddb79bbYMXGmQTsr5BeGS_RuZ5f_w xenolinux-2.4.16-sparse/Makefile
+16 -11
View File
@@ -54,29 +54,27 @@ net_vif_t *create_net_vif(int domain)
net_shadow_ring_t *shadow_ring;
struct task_struct *dom_task;
if ( !(dom_task = find_domain_by_id(domain)) )
{
return NULL;
}
if ( !(dom_task = find_domain_by_id(domain)) )
return NULL;
if ( (new_vif = kmem_cache_alloc(net_vif_cache, GFP_KERNEL)) == NULL )
{
return NULL;
}
return NULL;
new_ring = dom_task->net_ring_base + dom_task->num_net_vifs;
memset(new_ring, 0, sizeof(net_ring_t));
shadow_ring = kmalloc(sizeof(net_shadow_ring_t), GFP_KERNEL);
if (shadow_ring == NULL) goto fail;
if ( shadow_ring == NULL ) goto fail;
shadow_ring->rx_ring = kmalloc(RX_RING_SIZE
* sizeof(rx_shadow_entry_t), GFP_KERNEL);
if ( shadow_ring->rx_ring == NULL )
shadow_ring->tx_ring = kmalloc(TX_RING_SIZE
* sizeof(tx_shadow_entry_t), GFP_KERNEL);
if ( (shadow_ring->rx_ring == NULL) || (shadow_ring->tx_ring == NULL) )
goto fail;
shadow_ring->rx_prod = shadow_ring->rx_cons = shadow_ring->rx_idx = 0;
shadow_ring->tx_cons = 0;
shadow_ring->tx_prod = shadow_ring->tx_cons = shadow_ring->tx_idx = 0;
/* Fill in the new vif struct. */
@@ -98,7 +96,13 @@ net_vif_t *create_net_vif(int domain)
return new_vif;
fail:
printk("VIF allocation failed!\n");
kmem_cache_free(net_vif_cache, new_vif);
if ( shadow_ring != NULL )
{
if ( shadow_ring->rx_ring ) kfree(shadow_ring->rx_ring);
if ( shadow_ring->tx_ring ) kfree(shadow_ring->tx_ring);
kfree(shadow_ring);
}
return NULL;
}
@@ -125,6 +129,7 @@ void destroy_net_vif(struct task_struct *p)
sys_vif_list[p->net_vif_list[i]->id] = NULL; // system vif list not gc'ed
write_unlock(&sys_vif_lock);
kfree(p->net_vif_list[i]->shadow_ring->tx_ring);
kfree(p->net_vif_list[i]->shadow_ring->rx_ring);
kfree(p->net_vif_list[i]->shadow_ring);
kmem_cache_free(net_vif_cache, p->net_vif_list[i]);
+2 -8
View File
@@ -423,8 +423,7 @@ void ether_setup(struct net_device *dev)
dev->hard_header_len = ETH_HLEN;
dev->mtu = 1500; /* eth_mtu */
dev->addr_len = ETH_ALEN;
dev->tx_queue_len = 100; /* Ethernet wants good queues */
memset(dev->broadcast,0xFF, ETH_ALEN);
/* New-style flags. */
@@ -449,7 +448,6 @@ void fddi_setup(struct net_device *dev)
dev->hard_header_len = FDDI_K_SNAP_HLEN+3; /* Assume 802.2 SNAP hdr len + 3 pad bytes */
dev->mtu = FDDI_K_SNAP_DLEN; /* Assume max payload of 802.2 SNAP frame */
dev->addr_len = FDDI_K_ALEN;
dev->tx_queue_len = 100; /* Long queues on FDDI */
memset(dev->broadcast, 0xFF, FDDI_K_ALEN);
@@ -482,9 +480,8 @@ void hippi_setup(struct net_device *dev)
dev->hard_header_len = HIPPI_HLEN;
dev->mtu = 65280;
dev->addr_len = HIPPI_ALEN;
dev->tx_queue_len = 25 /* 5 */;
memset(dev->broadcast, 0xFF, HIPPI_ALEN);
memset(dev->broadcast, 0xFF, HIPPI_ALEN);
/*
* HIPPI doesn't support broadcast+multicast and we only use
@@ -523,7 +520,6 @@ void ltalk_setup(struct net_device *dev)
dev->hard_header_len = LTALK_HLEN;
dev->mtu = LTALK_MTU;
dev->addr_len = LTALK_ALEN;
dev->tx_queue_len = 10;
dev->broadcast[0] = 0xFF;
@@ -594,7 +590,6 @@ void tr_setup(struct net_device *dev)
dev->hard_header_len = TR_HLEN;
dev->mtu = 2000;
dev->addr_len = TR_ALEN;
dev->tx_queue_len = 100; /* Long queues on tr */
memset(dev->broadcast,0xFF, TR_ALEN);
@@ -671,7 +666,6 @@ void fc_setup(struct net_device *dev)
dev->hard_header_len = FC_HLEN;
dev->mtu = 2024;
dev->addr_len = FC_ALEN;
dev->tx_queue_len = 100; /* Long queues on fc */
memset(dev->broadcast,0xFF, FC_ALEN);
+6 -5
View File
@@ -6,10 +6,10 @@
#include <asm/byteorder.h>
#define TRY_SOFTIRQ
#ifdef TRY_SOFTIRQ
#define TRY_TASKLET
#ifdef TRY_TASKLET
/* XXX SMH: trying to use softirqs to trigger stuff done prev by threads */
#include <xeno/interrupt.h> /* for softirq stuff */
#include <xeno/interrupt.h> /* for tasklet/softirq stuff */
#endif
/*------------------------------------------------------------------------------
@@ -1408,8 +1408,9 @@ int aac_rx_init(struct aac_dev *dev, unsigned long devNumber);
int aac_sa_init(struct aac_dev *dev, unsigned long devNumber);
unsigned int aac_response_normal(struct aac_queue * q);
unsigned int aac_command_normal(struct aac_queue * q);
#ifdef TRY_SOFTIRQ
int aac_command_thread(struct softirq_action *h);
#ifdef TRY_TASKLET
extern struct tasklet_struct aac_command_tasklet;
int aac_command_thread(unsigned long data);
#else
int aac_command_thread(struct aac_dev * dev);
#endif
+12 -6
View File
@@ -39,7 +39,7 @@
#include <xeno/pci.h>
#include <xeno/spinlock.h>
#include <xeno/interrupt.h> // for softirq stuff
#include <xeno/interrupt.h> /* tasklet stuff */
/* #include <xeno/slab.h> */
/* #include <xeno/completion.h> */
@@ -529,10 +529,15 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
#if 0
down(&fibptr->event_wait);
#endif
#ifdef TRY_SOFTIRQ
#ifdef TRY_TASKLET
/*
* XXX KAF: Well, this is pretty gross. We should probably
* do_softirq() after scheduling the tasklet, as long as we
* are _sure_ we hold no locks here...
*/
printk("about to softirq aac_command_thread...\n");
while (!fibptr->done) {
raise_softirq(SCSI_LOW_SOFTIRQ);
tasklet_schedule(&aac_command_tasklet);
mdelay(100);
}
printk("back from softirq cmd thread and fibptr->done!\n");
@@ -837,13 +842,14 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
* more FIBs.
*/
#ifndef TRY_SOFTIRQ
#ifndef TRY_TASKLET
DECLARE_TASKLET_DISABLED(aac_command_tasklet, aac_command_thread, 0);
int aac_command_thread(struct aac_dev * dev)
{
#else
int aac_command_thread(struct softirq_action *h)
int aac_command_thread(unsigned long data)
{
struct aac_dev *dev = (struct aac_dev *)h->data;
struct aac_dev *dev = (struct aac_dev *)data;
#endif
struct hw_fib *fib, *newfib;
struct fib fibptr; /* for error logging */
+5 -5
View File
@@ -437,16 +437,16 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num)
if (aac_init_adapter(dev) == NULL)
return -1;
#if 0
#ifdef TRY_TASKLET
aac_command_tasklet.data = (unsigned long)dev;
tasklet_enable(&aac_command_tasklet);
#else
/*
* Start any kernel threads needed
*/
dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread,
dev, 0);
#else
/* XXX SMH: just put in a softirq handler instead... */
open_softirq(SCSI_LOW_SOFTIRQ, aac_command_thread, dev);
#endif
#endif
/*
* Tell the adapter that all is configured, and it can start
+10
View File
@@ -135,12 +135,19 @@ struct vlan_skb_tx_cookie {
u32 vlan_tag;
};
#if 0
#define VLAN_TX_COOKIE_MAGIC 0x564c414e /* "VLAN" in ascii. */
#define VLAN_TX_SKB_CB(__skb) ((struct vlan_skb_tx_cookie *)&((__skb)->cb[0]))
#define vlan_tx_tag_present(__skb) \
(VLAN_TX_SKB_CB(__skb)->magic == VLAN_TX_COOKIE_MAGIC)
#define vlan_tx_tag_get(__skb) (VLAN_TX_SKB_CB(__skb)->vlan_tag)
#else /* XXX KAF: We don't support vlan tagging at the moment. */
#define VLAN_TX_SKB_CB(__skb) NULL
#define vlan_tx_tag_present(__skb) 0
#define vlan_tx_tag_get(__skb) 0
#endif
#if 0
/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */
static inline int __vlan_hwaccel_rx(struct sk_buff *skb,
struct vlan_group *grp,
@@ -203,6 +210,9 @@ static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
{
return __vlan_hwaccel_rx(skb, grp, vlan_tag, 1);
}
#else
#define vlan_hwaccel_rx(_skb, _grp, _tag) (netif_rx(_skb))
#endif
#endif /* __KERNEL__ */
/* VLAN IOCTLs are found in sockios.h */
+2 -16
View File
@@ -27,19 +27,8 @@ struct irqaction {
enum {
TIMER_BH = 0,
TQUEUE_BH,
DIGI_BH,
SERIAL_BH,
RISCOM8_BH,
SPECIALIX_BH,
AURORA_BH,
ESP_BH,
SCSI_BH,
IMMEDIATE_BH,
CYCLADES_BH,
CM206_BH,
JS_BH,
MACSERIAL_BH,
ISICOM_BH
IMMEDIATE_BH
};
#include <asm/hardirq.h>
@@ -56,10 +45,7 @@ enum {
enum
{
HI_SOFTIRQ=0,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
TASKLET_SOFTIRQ,
SCSI_LOW_SOFTIRQ,
TASKLET_SOFTIRQ
};
/* softirq mask and active fields moved to irq_cpustat_t in
+20 -64
View File
@@ -25,17 +25,18 @@
#ifndef _LINUX_NETDEVICE_H
#define _LINUX_NETDEVICE_H
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/sched.h>
#include <xeno/if.h>
#include <xeno/if_ether.h>
#include <xeno/if_packet.h>
#include <xeno/sched.h>
#include <xeno/interrupt.h>
#include <asm/atomic.h>
#include <asm/cache.h>
#include <asm/byteorder.h>
#ifdef __KERNEL__
#include <linux/config.h>
#include <xeno/config.h>
struct divert_blk;
struct vlan_group;
@@ -65,28 +66,6 @@ struct vlan_group;
#define MAX_ADDR_LEN 8 /* Largest hardware address length */
/*
* Compute the worst case header length according to the protocols
* used.
*/
#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR)
#define LL_MAX_HEADER 32
#else
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
#define LL_MAX_HEADER 96
#else
#define LL_MAX_HEADER 48
#endif
#endif
#if !defined(CONFIG_NET_IPIP) && \
!defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE)
#define MAX_HEADER LL_MAX_HEADER
#else
#define MAX_HEADER (LL_MAX_HEADER + 48)
#endif
/*
* Network device statistics. Akin to the 2.0 ether stats but
* with byte counters.
@@ -141,8 +120,8 @@ enum {
extern const char *if_port_text[];
#include <linux/cache.h>
#include <linux/skbuff.h>
#include <xeno/cache.h>
#include <xeno/skbuff.h>
struct neighbour;
struct neigh_parms;
@@ -311,18 +290,6 @@ struct net_device
void *dn_ptr; /* DECnet specific data */
void *ip6_ptr; /* IPv6 specific data */
void *ec_ptr; /* Econet specific data */
#if 0
/* IAP: add fields but
nothing else */
struct list_head poll_list; /* Link to poll list */
int quota;
int weight;
#endif
struct Qdisc *qdisc;
struct Qdisc *qdisc_sleeping;
struct Qdisc *qdisc_list;
struct Qdisc *qdisc_ingress;
unsigned long tx_queue_len; /* Max frames per queue allowed */
/* hard_start_xmit synchronizer */
spinlock_t xmit_lock;
@@ -425,12 +392,10 @@ struct packet_type
};
#include <linux/interrupt.h>
//#include <linux/notifier.h>
#include <xeno/interrupt.h>
extern struct net_device loopback_dev; /* The loopback */
extern struct net_device *dev_base; /* All devices */
extern rwlock_t dev_base_lock; /* Device list lock */
extern struct net_device *dev_base; /* All devices */
extern rwlock_t dev_base_lock; /* Device list lock */
extern int netdev_boot_setup_add(char *name, struct ifmap *map);
extern int netdev_boot_setup_check(struct net_device *dev);
@@ -447,8 +412,10 @@ extern int dev_close(struct net_device *dev);
extern int dev_queue_xmit(struct sk_buff *skb);
extern int register_netdevice(struct net_device *dev);
extern int unregister_netdevice(struct net_device *dev);
//extern int register_netdevice_notifier(struct notifier_block *nb);
//extern int unregister_netdevice_notifier(struct notifier_block *nb);
extern void dev_shutdown(struct net_device *dev);
extern void dev_activate(struct net_device *dev);
extern void dev_deactivate(struct net_device *dev);
extern void dev_init_scheduler(struct net_device *dev);
extern int dev_new_index(void);
extern struct net_device *dev_get_by_index(int ifindex);
extern struct net_device *__dev_get_by_index(int ifindex);
@@ -461,17 +428,11 @@ static inline int unregister_gifconf(unsigned int family)
return register_gifconf(family, 0);
}
/*
* Incoming packets are placed on per-cpu queues so that
* no locking is needed.
*/
extern struct tasklet_struct net_tx_tasklet;
struct softnet_data
{
int throttle;
int cng_level;
int avg_blog;
struct sk_buff_head input_pkt_queue;
struct net_device *output_queue;
struct sk_buff *completion_queue;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
@@ -490,7 +451,7 @@ static inline void __netif_schedule(struct net_device *dev)
local_irq_save(flags);
dev->next_sched = softnet_data[cpu].output_queue;
softnet_data[cpu].output_queue = dev;
cpu_raise_softirq(cpu, NET_TX_SOFTIRQ);
tasklet_schedule(&net_tx_tasklet);
local_irq_restore(flags);
}
}
@@ -533,13 +494,13 @@ static inline int netif_running(struct net_device *dev)
static inline void dev_kfree_skb_irq(struct sk_buff *skb)
{
if (atomic_dec_and_test(&skb->users)) {
int cpu =smp_processor_id();
int cpu = smp_processor_id();
unsigned long flags;
local_irq_save(flags);
skb->next = softnet_data[cpu].completion_queue;
softnet_data[cpu].completion_queue = skb;
cpu_raise_softirq(cpu, NET_TX_SOFTIRQ);
tasklet_schedule(&net_tx_tasklet);
local_irq_restore(flags);
}
}
@@ -577,11 +538,6 @@ static inline int netif_rx_ni(struct sk_buff *skb)
return err;
}
static inline void dev_init_buffers(struct net_device *dev)
{
/* WILL BE REMOVED IN 2.5.0 */
}
extern int netdev_finish_unregister(struct net_device *dev);
static inline void dev_put(struct net_device *dev)
-816
View File
@@ -1,816 +0,0 @@
#ifndef __NET_PKT_SCHED_H
#define __NET_PKT_SCHED_H
#define PSCHED_GETTIMEOFDAY 1
#define PSCHED_JIFFIES 2
#define PSCHED_CPU 3
#define PSCHED_CLOCK_SOURCE PSCHED_JIFFIES
#include <linux/config.h>
#include <linux/pkt_sched.h>
//#include <net/pkt_cls.h>
#ifdef CONFIG_X86_TSC
#include <asm/msr.h>
#endif
struct rtattr;
struct Qdisc;
struct qdisc_walker
{
int stop;
int skip;
int count;
int (*fn)(struct Qdisc *, unsigned long cl, struct qdisc_walker *);
};
struct Qdisc_class_ops
{
/* Child qdisc manipulation */
int (*graft)(struct Qdisc *, unsigned long cl, struct Qdisc *, struct Qdisc **);
struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl);
/* Class manipulation routines */
unsigned long (*get)(struct Qdisc *, u32 classid);
void (*put)(struct Qdisc *, unsigned long);
int (*change)(struct Qdisc *, u32, u32, struct rtattr **, unsigned long *);
int (*delete)(struct Qdisc *, unsigned long);
void (*walk)(struct Qdisc *, struct qdisc_walker * arg);
#if 0
/* Filter manipulation */
struct tcf_proto ** (*tcf_chain)(struct Qdisc *, unsigned long);
unsigned long (*bind_tcf)(struct Qdisc *, unsigned long, u32 classid);
void (*unbind_tcf)(struct Qdisc *, unsigned long);
#endif
};
struct Qdisc_ops
{
struct Qdisc_ops *next;
struct Qdisc_class_ops *cl_ops;
char id[IFNAMSIZ];
int priv_size;
int (*enqueue)(struct sk_buff *, struct Qdisc *);
struct sk_buff * (*dequeue)(struct Qdisc *);
int (*requeue)(struct sk_buff *, struct Qdisc *);
int (*drop)(struct Qdisc *);
int (*init)(struct Qdisc *, struct rtattr *arg);
void (*reset)(struct Qdisc *);
void (*destroy)(struct Qdisc *);
int (*change)(struct Qdisc *, struct rtattr *arg);
int (*dump)(struct Qdisc *, struct sk_buff *);
};
extern rwlock_t qdisc_tree_lock;
struct Qdisc
{
int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
struct sk_buff * (*dequeue)(struct Qdisc *dev);
unsigned flags;
#define TCQ_F_BUILTIN 1
#define TCQ_F_THROTTLED 2
#define TCQ_F_INGRES 4
struct Qdisc_ops *ops;
struct Qdisc *next;
u32 handle;
atomic_t refcnt;
struct sk_buff_head q;
struct net_device *dev;
//struct tc_stats stats;
int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q);
/* This field is deprecated, but it is still used by CBQ
* and it will live until better solution will be invented.
*/
struct Qdisc *__parent;
char data[0];
};
struct qdisc_rate_table
{
//struct tc_ratespec rate;
u32 data[256];
struct qdisc_rate_table *next;
int refcnt;
};
static inline void sch_tree_lock(struct Qdisc *q)
{
write_lock(&qdisc_tree_lock);
spin_lock_bh(&q->dev->queue_lock);
}
static inline void sch_tree_unlock(struct Qdisc *q)
{
spin_unlock_bh(&q->dev->queue_lock);
write_unlock(&qdisc_tree_lock);
}
#if 0
static inline void tcf_tree_lock(struct tcf_proto *tp)
{
write_lock(&qdisc_tree_lock);
spin_lock_bh(&tp->q->dev->queue_lock);
}
static inline void tcf_tree_unlock(struct tcf_proto *tp)
{
spin_unlock_bh(&tp->q->dev->queue_lock);
write_unlock(&qdisc_tree_lock);
}
static inline unsigned long
cls_set_class(struct tcf_proto *tp, unsigned long *clp, unsigned long cl)
{
unsigned long old_cl;
tcf_tree_lock(tp);
old_cl = *clp;
*clp = cl;
tcf_tree_unlock(tp);
return old_cl;
}
static inline unsigned long
__cls_set_class(unsigned long *clp, unsigned long cl)
{
unsigned long old_cl;
old_cl = *clp;
*clp = cl;
return old_cl;
}
#endif
/*
Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth
Normal IP packet size ~ 512byte, hence:
0.5Kbyte/1Mbyte/sec = 0.5msec, so that we need 50usec timer for
10Mbit ethernet.
10msec resolution -> <50Kbit/sec.
The result: [34]86 is not good choice for QoS router :-(
The things are not so bad, because we may use artifical
clock evaluated by integration of network data flow
in the most critical places.
Note: we do not use fastgettimeofday.
The reason is that, when it is not the same thing as
gettimeofday, it returns invalid timestamp, which is
not updated, when net_bh is active.
So, use PSCHED_CLOCK_SOURCE = PSCHED_CPU on alpha and pentiums
with rtdsc. And PSCHED_JIFFIES on all other architectures, including [34]86
and pentiums without rtdsc.
You can use PSCHED_GETTIMEOFDAY on another architectures,
which have fast and precise clock source, but it is too expensive.
*/
/* General note about internal clock.
Any clock source returns time intervals, measured in units
close to 1usec. With source PSCHED_GETTIMEOFDAY it is precisely
microseconds, otherwise something close but different chosen to minimize
arithmetic cost. Ratio usec/internal untis in form nominator/denominator
may be read from /proc/net/psched.
*/
#if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY
typedef struct timeval psched_time_t;
typedef long psched_tdiff_t;
#define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp))
#define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ))
#define PSCHED_EXPORTLIST EXPORT_SYMBOL(psched_tod_diff);
#else /* PSCHED_CLOCK_SOURCE != PSCHED_GETTIMEOFDAY */
#define PSCHED_EXPORTLIST PSCHED_EXPORTLIST_1 PSCHED_EXPORTLIST_2
typedef u64 psched_time_t;
typedef long psched_tdiff_t;
extern psched_time_t psched_time_base;
#if PSCHED_CLOCK_SOURCE == PSCHED_JIFFIES
#if HZ == 100
#define PSCHED_JSCALE 13
#elif HZ == 1024
#define PSCHED_JSCALE 10
#else
#define PSCHED_JSCALE 0
#endif
#define PSCHED_EXPORTLIST_2
#if ~0UL == 0xFFFFFFFF
#define PSCHED_WATCHER unsigned long
extern PSCHED_WATCHER psched_time_mark;
#define PSCHED_GET_TIME(stamp) ((stamp) = psched_time_base + (((unsigned long)(jiffies-psched_time_mark))<<PSCHED_JSCALE))
#define PSCHED_EXPORTLIST_1 EXPORT_SYMBOL(psched_time_base); \
EXPORT_SYMBOL(psched_time_mark);
#else
#define PSCHED_GET_TIME(stamp) ((stamp) = (jiffies<<PSCHED_JSCALE))
#define PSCHED_EXPORTLIST_1
#endif
#define PSCHED_US2JIFFIE(delay) (((delay)+(1<<PSCHED_JSCALE)-1)>>PSCHED_JSCALE)
#elif PSCHED_CLOCK_SOURCE == PSCHED_CPU
extern psched_tdiff_t psched_clock_per_hz;
extern int psched_clock_scale;
#define PSCHED_EXPORTLIST_2 EXPORT_SYMBOL(psched_clock_per_hz); \
EXPORT_SYMBOL(psched_clock_scale);
#define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz)
#ifdef CONFIG_X86_TSC
#define PSCHED_GET_TIME(stamp) \
({ u64 __cur; \
rdtscll(__cur); \
(stamp) = __cur>>psched_clock_scale; \
})
#define PSCHED_EXPORTLIST_1
#elif defined (__alpha__)
#define PSCHED_WATCHER u32
extern PSCHED_WATCHER psched_time_mark;
#define PSCHED_GET_TIME(stamp) \
({ u32 __res; \
__asm__ __volatile__ ("rpcc %0" : "r="(__res)); \
if (__res <= psched_time_mark) psched_time_base += 0x100000000UL; \
psched_time_mark = __res; \
(stamp) = (psched_time_base + __res)>>psched_clock_scale; \
})
#define PSCHED_EXPORTLIST_1 EXPORT_SYMBOL(psched_time_base); \
EXPORT_SYMBOL(psched_time_mark);
#else
#error PSCHED_CLOCK_SOURCE=PSCHED_CPU is not supported on this arch.
#endif /* ARCH */
#endif /* PSCHED_CLOCK_SOURCE == PSCHED_JIFFIES */
#endif /* PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY */
#if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY
#define PSCHED_TDIFF(tv1, tv2) \
({ \
int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
int __delta = (tv1).tv_usec - (tv2).tv_usec; \
if (__delta_sec) { \
switch (__delta_sec) { \
default: \
__delta = 0; \
case 2: \
__delta += 1000000; \
case 1: \
__delta += 1000000; \
} \
} \
__delta; \
})
extern int psched_tod_diff(int delta_sec, int bound);
#define PSCHED_TDIFF_SAFE(tv1, tv2, bound, guard) \
({ \
int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
int __delta = (tv1).tv_usec - (tv2).tv_usec; \
switch (__delta_sec) { \
default: \
__delta = psched_tod_diff(__delta_sec, bound); guard; break; \
case 2: \
__delta += 1000000; \
case 1: \
__delta += 1000000; \
case 0: ; \
} \
__delta; \
})
#define PSCHED_TLESS(tv1, tv2) (((tv1).tv_usec < (tv2).tv_usec && \
(tv1).tv_sec <= (tv2).tv_sec) || \
(tv1).tv_sec < (tv2).tv_sec)
#define PSCHED_TADD2(tv, delta, tv_res) \
({ \
int __delta = (tv).tv_usec + (delta); \
(tv_res).tv_sec = (tv).tv_sec; \
if (__delta > 1000000) { (tv_res).tv_sec++; __delta -= 1000000; } \
(tv_res).tv_usec = __delta; \
})
#define PSCHED_TADD(tv, delta) \
({ \
(tv).tv_usec += (delta); \
if ((tv).tv_usec > 1000000) { (tv).tv_sec++; \
(tv).tv_usec -= 1000000; } \
})
/* Set/check that time is in the "past perfect";
it depends on concrete representation of system time
*/
#define PSCHED_SET_PASTPERFECT(t) ((t).tv_sec = 0)
#define PSCHED_IS_PASTPERFECT(t) ((t).tv_sec == 0)
#define PSCHED_AUDIT_TDIFF(t) ({ if ((t) > 2000000) (t) = 2000000; })
#else
#define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2))
#define PSCHED_TDIFF_SAFE(tv1, tv2, bound, guard) \
({ \
long __delta = (tv1) - (tv2); \
if ( __delta > (bound)) { __delta = (bound); guard; } \
__delta; \
})
#define PSCHED_TLESS(tv1, tv2) ((tv1) < (tv2))
#define PSCHED_TADD2(tv, delta, tv_res) ((tv_res) = (tv) + (delta))
#define PSCHED_TADD(tv, delta) ((tv) += (delta))
#define PSCHED_SET_PASTPERFECT(t) ((t) = 0)
#define PSCHED_IS_PASTPERFECT(t) ((t) == 0)
#define PSCHED_AUDIT_TDIFF(t)
#endif
struct tcf_police
{
struct tcf_police *next;
int refcnt;
u32 index;
int action;
int result;
u32 ewma_rate;
u32 burst;
u32 mtu;
u32 toks;
u32 ptoks;
psched_time_t t_c;
spinlock_t lock;
struct qdisc_rate_table *R_tab;
struct qdisc_rate_table *P_tab;
//struct tc_stats stats;
};
//extern int qdisc_copy_stats(struct sk_buff *skb, struct tc_stats *st);
extern void tcf_police_destroy(struct tcf_police *p);
extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est);
extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p);
extern int tcf_police(struct sk_buff *skb, struct tcf_police *p);
static inline void tcf_police_release(struct tcf_police *p)
{
if (p && --p->refcnt == 0)
tcf_police_destroy(p);
}
extern struct Qdisc noop_qdisc;
extern struct Qdisc_ops noop_qdisc_ops;
extern struct Qdisc_ops pfifo_qdisc_ops;
extern struct Qdisc_ops bfifo_qdisc_ops;
int register_qdisc(struct Qdisc_ops *qops);
int unregister_qdisc(struct Qdisc_ops *qops);
struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
void dev_init_scheduler(struct net_device *dev);
void dev_shutdown(struct net_device *dev);
void dev_activate(struct net_device *dev);
void dev_deactivate(struct net_device *dev);
void qdisc_reset(struct Qdisc *qdisc);
void qdisc_destroy(struct Qdisc *qdisc);
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops);
//int qdisc_new_estimator(struct tc_stats *stats, struct rtattr *opt);
//void qdisc_kill_estimator(struct tc_stats *stats);
//struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab);
void qdisc_put_rtab(struct qdisc_rate_table *tab);
int teql_init(void);
int tc_filter_init(void);
int pktsched_init(void);
extern int qdisc_restart(struct net_device *dev);
static inline void qdisc_run(struct net_device *dev)
{
while (!netif_queue_stopped(dev) &&
qdisc_restart(dev)<0)
/* NOTHING */;
}
/* Calculate maximal size of packet seen by hard_start_xmit
routine of this device.
*/
static inline unsigned psched_mtu(struct net_device *dev)
{
unsigned mtu = dev->mtu;
return dev->hard_header ? mtu + dev->hard_header_len : mtu;
}
/******************************************************************************
* XXXXXXXXX Rest of this file is real linux/pkt_sched.h XXXXX
*/
/* Logical priority bands not depending on specific packet scheduler.
Every scheduler will map them to real traffic classes, if it has
no more precise mechanism to classify packets.
These numbers have no special meaning, though their coincidence
with obsolete IPv6 values is not occasional :-). New IPv6 drafts
preferred full anarchy inspired by diffserv group.
Note: TC_PRIO_BESTEFFORT does not mean that it is the most unhappy
class, actually, as rule it will be handled with more care than
filler or even bulk.
*/
#define TC_PRIO_BESTEFFORT 0
#define TC_PRIO_FILLER 1
#define TC_PRIO_BULK 2
#define TC_PRIO_INTERACTIVE_BULK 4
#define TC_PRIO_INTERACTIVE 6
#define TC_PRIO_CONTROL 7
#define TC_PRIO_MAX 15
/* Generic queue statistics, available for all the elements.
Particular schedulers may have also their private records.
*/
struct tc_stats
{
__u64 bytes; /* NUmber of enqueues bytes */
__u32 packets; /* Number of enqueued packets */
__u32 drops; /* Packets dropped because of lack of resources */
__u32 overlimits; /* Number of throttle events when this
* flow goes out of allocated bandwidth */
__u32 bps; /* Current flow byte rate */
__u32 pps; /* Current flow packet rate */
__u32 qlen;
__u32 backlog;
#ifdef __KERNEL__
spinlock_t *lock;
#endif
};
struct tc_estimator
{
char interval;
unsigned char ewma_log;
};
/* "Handles"
---------
All the traffic control objects have 32bit identifiers, or "handles".
They can be considered as opaque numbers from user API viewpoint,
but actually they always consist of two fields: major and
minor numbers, which are interpreted by kernel specially,
that may be used by applications, though not recommended.
F.e. qdisc handles always have minor number equal to zero,
classes (or flows) have major equal to parent qdisc major, and
minor uniquely identifying class inside qdisc.
Macros to manipulate handles:
*/
#define TC_H_MAJ_MASK (0xFFFF0000U)
#define TC_H_MIN_MASK (0x0000FFFFU)
#define TC_H_MAJ(h) ((h)&TC_H_MAJ_MASK)
#define TC_H_MIN(h) ((h)&TC_H_MIN_MASK)
#define TC_H_MAKE(maj,min) (((maj)&TC_H_MAJ_MASK)|((min)&TC_H_MIN_MASK))
#define TC_H_UNSPEC (0U)
#define TC_H_ROOT (0xFFFFFFFFU)
#define TC_H_INGRESS (0xFFFFFFF1U)
struct tc_ratespec
{
unsigned char cell_log;
unsigned char __reserved;
unsigned short feature;
short addend;
unsigned short mpu;
__u32 rate;
};
/* FIFO section */
struct tc_fifo_qopt
{
__u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */
};
/* PRIO section */
#define TCQ_PRIO_BANDS 16
struct tc_prio_qopt
{
int bands; /* Number of bands */
__u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
};
/* CSZ section */
struct tc_csz_qopt
{
int flows; /* Maximal number of guaranteed flows */
unsigned char R_log; /* Fixed point position for round number */
unsigned char delta_log; /* Log of maximal managed time interval */
__u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> CSZ band */
};
struct tc_csz_copt
{
struct tc_ratespec slice;
struct tc_ratespec rate;
struct tc_ratespec peakrate;
__u32 limit;
__u32 buffer;
__u32 mtu;
};
enum
{
TCA_CSZ_UNSPEC,
TCA_CSZ_PARMS,
TCA_CSZ_RTAB,
TCA_CSZ_PTAB,
};
/* TBF section */
struct tc_tbf_qopt
{
struct tc_ratespec rate;
struct tc_ratespec peakrate;
__u32 limit;
__u32 buffer;
__u32 mtu;
};
enum
{
TCA_TBF_UNSPEC,
TCA_TBF_PARMS,
TCA_TBF_RTAB,
TCA_TBF_PTAB,
};
/* TEQL section */
/* TEQL does not require any parameters */
/* SFQ section */
struct tc_sfq_qopt
{
unsigned quantum; /* Bytes per round allocated to flow */
int perturb_period; /* Period of hash perturbation */
__u32 limit; /* Maximal packets in queue */
unsigned divisor; /* Hash divisor */
unsigned flows; /* Maximal number of flows */
};
/*
* NOTE: limit, divisor and flows are hardwired to code at the moment.
*
* limit=flows=128, divisor=1024;
*
* The only reason for this is efficiency, it is possible
* to change these parameters in compile time.
*/
/* RED section */
enum
{
TCA_RED_UNSPEC,
TCA_RED_PARMS,
TCA_RED_STAB,
};
struct tc_red_qopt
{
__u32 limit; /* HARD maximal queue length (bytes) */
__u32 qth_min; /* Min average length threshold (bytes) */
__u32 qth_max; /* Max average length threshold (bytes) */
unsigned char Wlog; /* log(W) */
unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
unsigned char Scell_log; /* cell size for idle damping */
unsigned char flags;
#define TC_RED_ECN 1
};
struct tc_red_xstats
{
__u32 early; /* Early drops */
__u32 pdrop; /* Drops due to queue limits */
__u32 other; /* Drops due to drop() calls */
__u32 marked; /* Marked packets */
};
/* GRED section */
#define MAX_DPs 16
enum
{
TCA_GRED_UNSPEC,
TCA_GRED_PARMS,
TCA_GRED_STAB,
TCA_GRED_DPS,
};
#define TCA_SET_OFF TCA_GRED_PARMS
struct tc_gred_qopt
{
__u32 limit; /* HARD maximal queue length (bytes)
*/
__u32 qth_min; /* Min average length threshold (bytes)
*/
__u32 qth_max; /* Max average length threshold (bytes)
*/
__u32 DP; /* upto 2^32 DPs */
__u32 backlog;
__u32 qave;
__u32 forced;
__u32 early;
__u32 other;
__u32 pdrop;
unsigned char Wlog; /* log(W) */
unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
unsigned char Scell_log; /* cell size for idle damping */
__u8 prio; /* prio of this VQ */
__u32 packets;
__u32 bytesin;
};
/* gred setup */
struct tc_gred_sopt
{
__u32 DPs;
__u32 def_DP;
__u8 grio;
};
/* CBQ section */
#define TC_CBQ_MAXPRIO 8
#define TC_CBQ_MAXLEVEL 8
#define TC_CBQ_DEF_EWMA 5
struct tc_cbq_lssopt
{
unsigned char change;
unsigned char flags;
#define TCF_CBQ_LSS_BOUNDED 1
#define TCF_CBQ_LSS_ISOLATED 2
unsigned char ewma_log;
unsigned char level;
#define TCF_CBQ_LSS_FLAGS 1
#define TCF_CBQ_LSS_EWMA 2
#define TCF_CBQ_LSS_MAXIDLE 4
#define TCF_CBQ_LSS_MINIDLE 8
#define TCF_CBQ_LSS_OFFTIME 0x10
#define TCF_CBQ_LSS_AVPKT 0x20
__u32 maxidle;
__u32 minidle;
__u32 offtime;
__u32 avpkt;
};
struct tc_cbq_wrropt
{
unsigned char flags;
unsigned char priority;
unsigned char cpriority;
unsigned char __reserved;
__u32 allot;
__u32 weight;
};
struct tc_cbq_ovl
{
unsigned char strategy;
#define TC_CBQ_OVL_CLASSIC 0
#define TC_CBQ_OVL_DELAY 1
#define TC_CBQ_OVL_LOWPRIO 2
#define TC_CBQ_OVL_DROP 3
#define TC_CBQ_OVL_RCLASSIC 4
unsigned char priority2;
__u32 penalty;
};
struct tc_cbq_police
{
unsigned char police;
unsigned char __res1;
unsigned short __res2;
};
struct tc_cbq_fopt
{
__u32 split;
__u32 defmap;
__u32 defchange;
};
struct tc_cbq_xstats
{
__u32 borrows;
__u32 overactions;
__s32 avgidle;
__s32 undertime;
};
enum
{
TCA_CBQ_UNSPEC,
TCA_CBQ_LSSOPT,
TCA_CBQ_WRROPT,
TCA_CBQ_FOPT,
TCA_CBQ_OVL_STRATEGY,
TCA_CBQ_RATE,
TCA_CBQ_RTAB,
TCA_CBQ_POLICE,
};
#define TCA_CBQ_MAX TCA_CBQ_POLICE
/* dsmark section */
enum {
TCA_DSMARK_UNSPEC,
TCA_DSMARK_INDICES,
TCA_DSMARK_DEFAULT_INDEX,
TCA_DSMARK_SET_TC_INDEX,
TCA_DSMARK_MASK,
TCA_DSMARK_VALUE
};
#define TCA_DSMARK_MAX TCA_DSMARK_VALUE
/* ATM section */
enum {
TCA_ATM_UNSPEC,
TCA_ATM_FD, /* file/socket descriptor */
TCA_ATM_PTR, /* pointer to descriptor - later */
TCA_ATM_HDR, /* LL header */
TCA_ATM_EXCESS, /* excess traffic class (0 for CLP) */
TCA_ATM_ADDR, /* PVC address (for output only) */
TCA_ATM_STATE /* VC state (ATM_VS_*; for output only) */
};
#define TCA_ATM_MAX TCA_ATM_STATE
#endif
+1 -50
View File
@@ -16,8 +16,6 @@
#include <linux/config.h>
#include <linux/lib.h>
//#include <linux/kernel.h>
//#include <linux/sched.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/cache.h>
@@ -26,7 +24,6 @@
#include <asm/types.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
//#include <linux/highmem.h>
// vif special values.
#define VIF_PHYSICAL_INTERFACE -1
@@ -144,8 +141,6 @@ struct sk_buff {
struct sk_buff * prev; /* Previous buffer in list */
struct sk_buff_head * list; /* List we are on */
struct sock *sk; /* Socket we are owned by */
struct timeval stamp; /* Time we arrived */
struct net_device *dev; /* Device we arrived on/are leaving by */
/* Transport layer header */
@@ -177,66 +172,25 @@ struct sk_buff {
unsigned char *raw;
} mac;
// struct dst_entry *dst;
/*
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[48];
unsigned int len; /* Length of actual data */
unsigned int data_len;
unsigned int csum; /* Checksum */
unsigned char __unused, /* Dead field, may be reused */
unsigned char skb_type,
cloned, /* head may be cloned (check refcnt to be sure) */
pkt_type, /* Packet class */
ip_summed; /* Driver fed us an IP checksum */
__u32 priority; /* Packet queueing priority */
atomic_t users; /* User count - see datagram.c,tcp.c */
unsigned short protocol; /* Packet protocol from driver. */
unsigned short security; /* Security level of packet */
unsigned int truesize; /* Buffer size */
unsigned char *head; /* Head of buffer */
unsigned char *data; /* Data head pointer */
unsigned char *tail; /* Tail pointer */
unsigned char *end; /* End pointer */
void (*destructor)(struct sk_buff *); /* Destruct function */
unsigned int skb_type; /* SKB_NORMAL or SKB_ZERO_COPY */
struct pfn_info *pf; /* record of physical pf address for freeing */
int src_vif; /* vif we came from */
int dst_vif; /* vif we are bound for */
struct skb_shared_info shinfo; /* shared info is no longer shared in Xen. */
#ifdef CONFIG_NETFILTER
/* Can be used for communication between hooks. */
unsigned long nfmark;
/* Cache info */
__u32 nfcache;
/* Associated connection, if any */
struct nf_ct_info *nfct;
#ifdef CONFIG_NETFILTER_DEBUG
unsigned int nf_debug;
#endif
#endif /*CONFIG_NETFILTER*/
#if defined(CONFIG_HIPPI)
union{
__u32 ifield;
} private;
#endif
#ifdef CONFIG_NET_SCHED
__u32 tc_index; /* traffic control index */
#endif
};
#define SK_WMEM_MAX 65535
@@ -1000,7 +954,6 @@ static inline void skb_orphan(struct sk_buff *skb)
if (skb->destructor)
skb->destructor(skb);
skb->destructor = NULL;
skb->sk = NULL;
}
/**
@@ -1130,10 +1083,8 @@ static inline void kunmap_skb_frag(void *vaddr)
skb=skb->next)
extern struct sk_buff * skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err);
extern int skb_copy_datagram(const struct sk_buff *from, int offset, char *to,int size);
extern int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, u8 *to, int len, unsigned int *csump);
extern void skb_free_datagram(struct sock * sk, struct sk_buff *skb);
extern unsigned int skb_checksum(const struct sk_buff *skb, int offset, int len, unsigned int csum);
extern int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len);
-3
View File
@@ -69,9 +69,6 @@
#define SIOCGIFBR 0x8940 /* Bridging support */
#define SIOCSIFBR 0x8941 /* Set bridging options */
#define SIOCGIFTXQLEN 0x8942 /* Get the tx queue length */
#define SIOCSIFTXQLEN 0x8943 /* Set the tx queue length */
#define SIOCGIFDIVERT 0x8944 /* Frame diversion support */
#define SIOCSIFDIVERT 0x8945 /* Set frame diversion options */
+8 -1
View File
@@ -32,10 +32,17 @@ typedef struct rx_shadow_entry_st {
unsigned long flush_count;
} rx_shadow_entry_t;
typedef struct tx_shadow_entry_st {
unsigned long addr;
unsigned long size;
int status;
} tx_shadow_entry_t;
typedef struct net_shadow_ring_st {
rx_shadow_entry_t *rx_ring;
tx_shadow_entry_t *tx_ring;
unsigned int rx_prod, rx_cons, rx_idx;
unsigned int tx_cons; /* ahead of shared tx_cons */
unsigned int tx_prod, tx_cons, tx_idx;
} net_shadow_ring_t;
typedef struct net_vif_st {
+1093 -1177
View File
File diff suppressed because it is too large. Load diff
+114
View File
@@ -0,0 +1,114 @@
/******************************************************************************
* devinit.c
*
* This is the watchdog timer routines, ripped from sch_generic.c
* Original copyright notice appears below.
*
*/
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
* Jamal Hadi Salim, <hadi@nortelnetworks.com> 990601
* - Ingress support
*/
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/lib.h>
#include <linux/mm.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
static void dev_watchdog(unsigned long arg)
{
struct net_device *dev = (struct net_device *)arg;
spin_lock(&dev->xmit_lock);
if (netif_device_present(dev) &&
netif_running(dev) &&
netif_carrier_ok(dev)) {
if (netif_queue_stopped(dev) &&
(jiffies - dev->trans_start) > dev->watchdog_timeo) {
printk(KERN_INFO "NETDEV WATCHDOG: %s: transmit timed out\n", dev->name);
dev->tx_timeout(dev);
}
if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo))
dev_hold(dev);
}
spin_unlock(&dev->xmit_lock);
dev_put(dev);
}
static void dev_watchdog_init(struct net_device *dev)
{
init_timer(&dev->watchdog_timer);
dev->watchdog_timer.data = (unsigned long)dev;
dev->watchdog_timer.function = dev_watchdog;
}
void __netdev_watchdog_up(struct net_device *dev)
{
if (dev->tx_timeout) {
if (dev->watchdog_timeo <= 0)
dev->watchdog_timeo = 5*HZ;
if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo))
dev_hold(dev);
}
}
static void dev_watchdog_up(struct net_device *dev)
{
spin_lock_bh(&dev->xmit_lock);
__netdev_watchdog_up(dev);
spin_unlock_bh(&dev->xmit_lock);
}
static void dev_watchdog_down(struct net_device *dev)
{
spin_lock_bh(&dev->xmit_lock);
if (del_timer(&dev->watchdog_timer))
__dev_put(dev);
spin_unlock_bh(&dev->xmit_lock);
}
void dev_activate(struct net_device *dev)
{
spin_lock_bh(&dev->queue_lock);
dev->trans_start = jiffies;
dev_watchdog_up(dev);
spin_unlock_bh(&dev->queue_lock);
}
void dev_deactivate(struct net_device *dev)
{
dev_watchdog_down(dev);
while (test_bit(__LINK_STATE_SCHED, &dev->state)) {
current->policy |= SCHED_YIELD;
schedule();
}
}
void dev_init_scheduler(struct net_device *dev)
{
dev_watchdog_init(dev);
}
void dev_shutdown(struct net_device *dev)
{
}
-525
View File
@@ -1,525 +0,0 @@
/*
* net/sched/sch_generic.c Generic packet scheduler routines.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
* Jamal Hadi Salim, <hadi@nortelnetworks.com> 990601
* - Ingress support
*/
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <linux/config.h>
#include <linux/types.h>
//#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/lib.h>
#include <linux/mm.h>
#include <linux/socket.h>
#include <linux/sockios.h>
//#include <linux/in.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
//#include <linux/rtnetlink.h>
#include <linux/init.h>
//#include <net/sock.h>
#include <linux/pkt_sched.h>
extern int net_ratelimit(void);
#define BUG_TRAP ASSERT
/* Main transmission queue. */
/* Main qdisc structure lock.
However, modifications
to data, participating in scheduling must be additionally
protected with dev->queue_lock spinlock.
The idea is the following:
- enqueue, dequeue are serialized via top level device
spinlock dev->queue_lock.
- tree walking is protected by read_lock(qdisc_tree_lock)
and this lock is used only in process context.
- updates to tree are made only under rtnl semaphore,
hence this lock may be made without local bh disabling.
qdisc_tree_lock must be grabbed BEFORE dev->queue_lock!
*/
rwlock_t qdisc_tree_lock = RW_LOCK_UNLOCKED;
/*
dev->queue_lock serializes queue accesses for this device
AND dev->qdisc pointer itself.
dev->xmit_lock serializes accesses to device driver.
dev->queue_lock and dev->xmit_lock are mutually exclusive,
if one is grabbed, another must be free.
*/
/* Kick device.
Note, that this procedure can be called by a watchdog timer, so that
we do not check dev->tbusy flag here.
Returns: 0 - queue is empty.
>0 - queue is not empty, but throttled.
<0 - queue is not empty. Device is throttled, if dev->tbusy != 0.
NOTE: Called under dev->queue_lock with locally disabled BH.
*/
int qdisc_restart(struct net_device *dev)
{
struct Qdisc *q = dev->qdisc;
struct sk_buff *skb;
/* Dequeue packet */
if ((skb = q->dequeue(q)) != NULL) {
if (spin_trylock(&dev->xmit_lock)) {
/* Remember that the driver is grabbed by us. */
dev->xmit_lock_owner = smp_processor_id();
/* And release queue */
spin_unlock(&dev->queue_lock);
if (!netif_queue_stopped(dev)) {
#if 0
if (netdev_nit)
dev_queue_xmit_nit(skb, dev);
#endif
if (dev->hard_start_xmit(skb, dev) == 0) {
dev->xmit_lock_owner = -1;
spin_unlock(&dev->xmit_lock);
spin_lock(&dev->queue_lock);
return -1;
}
}
/* Release the driver */
dev->xmit_lock_owner = -1;
spin_unlock(&dev->xmit_lock);
spin_lock(&dev->queue_lock);
q = dev->qdisc;
} else {
/* So, someone grabbed the driver. */
/* It may be transient configuration error,
when hard_start_xmit() recurses. We detect
it by checking xmit owner and drop the
packet when deadloop is detected.
*/
if (dev->xmit_lock_owner == smp_processor_id()) {
kfree_skb(skb);
if (net_ratelimit())
printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name);
return -1;
}
netdev_rx_stat[smp_processor_id()].cpu_collision++;
}
/* Device kicked us out :(
This is possible in three cases:
0. driver is locked
1. fastroute is enabled
2. device cannot determine busy state
before start of transmission (f.e. dialout)
3. device is buggy (ppp)
*/
q->ops->requeue(skb, q);
netif_schedule(dev);
return 1;
}
return q->q.qlen;
}
static void dev_watchdog(unsigned long arg)
{
struct net_device *dev = (struct net_device *)arg;
spin_lock(&dev->xmit_lock);
if (dev->qdisc != &noop_qdisc) {
if (netif_device_present(dev) &&
netif_running(dev) &&
netif_carrier_ok(dev)) {
if (netif_queue_stopped(dev) &&
(jiffies - dev->trans_start) > dev->watchdog_timeo) {
printk(KERN_INFO "NETDEV WATCHDOG: %s: transmit timed out\n", dev->name);
dev->tx_timeout(dev);
}
if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo))
dev_hold(dev);
}
}
spin_unlock(&dev->xmit_lock);
dev_put(dev);
}
static void dev_watchdog_init(struct net_device *dev)
{
init_timer(&dev->watchdog_timer);
dev->watchdog_timer.data = (unsigned long)dev;
dev->watchdog_timer.function = dev_watchdog;
}
void __netdev_watchdog_up(struct net_device *dev)
{
if (dev->tx_timeout) {
if (dev->watchdog_timeo <= 0)
dev->watchdog_timeo = 5*HZ;
if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo))
dev_hold(dev);
}
}
static void dev_watchdog_up(struct net_device *dev)
{
spin_lock_bh(&dev->xmit_lock);
__netdev_watchdog_up(dev);
spin_unlock_bh(&dev->xmit_lock);
}
static void dev_watchdog_down(struct net_device *dev)
{
spin_lock_bh(&dev->xmit_lock);
if (del_timer(&dev->watchdog_timer))
__dev_put(dev);
spin_unlock_bh(&dev->xmit_lock);
}
/* "NOOP" scheduler: the best scheduler, recommended for all interfaces
under all circumstances. It is difficult to invent anything faster or
cheaper.
*/
static int
noop_enqueue(struct sk_buff *skb, struct Qdisc * qdisc)
{
kfree_skb(skb);
return NET_XMIT_CN;
}
static struct sk_buff *
noop_dequeue(struct Qdisc * qdisc)
{
return NULL;
}
static int
noop_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
{
if (net_ratelimit())
printk(KERN_DEBUG "%s deferred output. It is buggy.\n", skb->dev->name);
kfree_skb(skb);
return NET_XMIT_CN;
}
struct Qdisc_ops noop_qdisc_ops =
{
NULL,
NULL,
"noop",
0,
noop_enqueue,
noop_dequeue,
noop_requeue,
};
struct Qdisc noop_qdisc =
{
noop_enqueue,
noop_dequeue,
TCQ_F_BUILTIN,
&noop_qdisc_ops,
};
struct Qdisc_ops noqueue_qdisc_ops =
{
NULL,
NULL,
"noqueue",
0,
noop_enqueue,
noop_dequeue,
noop_requeue,
};
struct Qdisc noqueue_qdisc =
{
NULL,
noop_dequeue,
TCQ_F_BUILTIN,
&noqueue_qdisc_ops,
};
static const u8 prio2band[TC_PRIO_MAX+1] =
{ 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 };
/* 3-band FIFO queue: old style, but should be a bit faster than
generic prio+fifo combination.
*/
static int
pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
{
struct sk_buff_head *list;
list = ((struct sk_buff_head*)qdisc->data) +
prio2band[skb->priority&TC_PRIO_MAX];
if (list->qlen <= skb->dev->tx_queue_len) {
__skb_queue_tail(list, skb);
qdisc->q.qlen++;
return 0;
}
//qdisc->stats.drops++;
kfree_skb(skb);
return NET_XMIT_DROP;
}
static struct sk_buff *
pfifo_fast_dequeue(struct Qdisc* qdisc)
{
int prio;
struct sk_buff_head *list = ((struct sk_buff_head*)qdisc->data);
struct sk_buff *skb;
for (prio = 0; prio < 3; prio++, list++) {
skb = __skb_dequeue(list);
if (skb) {
qdisc->q.qlen--;
return skb;
}
}
return NULL;
}
static int
pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
{
struct sk_buff_head *list;
list = ((struct sk_buff_head*)qdisc->data) +
prio2band[skb->priority&TC_PRIO_MAX];
__skb_queue_head(list, skb);
qdisc->q.qlen++;
return 0;
}
static void
pfifo_fast_reset(struct Qdisc* qdisc)
{
int prio;
struct sk_buff_head *list = ((struct sk_buff_head*)qdisc->data);
for (prio=0; prio < 3; prio++)
skb_queue_purge(list+prio);
qdisc->q.qlen = 0;
}
static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt)
{
int i;
struct sk_buff_head *list;
list = ((struct sk_buff_head*)qdisc->data);
for (i=0; i<3; i++)
skb_queue_head_init(list+i);
return 0;
}
static struct Qdisc_ops pfifo_fast_ops =
{
NULL,
NULL,
"pfifo_fast",
3 * sizeof(struct sk_buff_head),
pfifo_fast_enqueue,
pfifo_fast_dequeue,
pfifo_fast_requeue,
NULL,
pfifo_fast_init,
pfifo_fast_reset,
};
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
{
struct Qdisc *sch;
int size = sizeof(*sch) + ops->priv_size;
sch = kmalloc(size, GFP_KERNEL);
if (!sch)
return NULL;
memset(sch, 0, size);
skb_queue_head_init(&sch->q);
sch->ops = ops;
sch->enqueue = ops->enqueue;
sch->dequeue = ops->dequeue;
sch->dev = dev;
//sch->stats.lock = &dev->queue_lock;
atomic_set(&sch->refcnt, 1);
if (!ops->init || ops->init(sch, NULL) == 0)
return sch;
kfree(sch);
return NULL;
}
/* Under dev->queue_lock and BH! */
void qdisc_reset(struct Qdisc *qdisc)
{
struct Qdisc_ops *ops = qdisc->ops;
if (ops->reset)
ops->reset(qdisc);
}
/* Under dev->queue_lock and BH! */
void qdisc_destroy(struct Qdisc *qdisc)
{
struct Qdisc_ops *ops = qdisc->ops;
struct net_device *dev;
if (!atomic_dec_and_test(&qdisc->refcnt))
return;
dev = qdisc->dev;
#ifdef CONFIG_NET_SCHED
if (dev) {
struct Qdisc *q, **qp;
for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) {
if (q == qdisc) {
*qp = q->next;
break;
}
}
}
#ifdef CONFIG_NET_ESTIMATOR
qdisc_kill_estimator(&qdisc->stats);
#endif
#endif
if (ops->reset)
ops->reset(qdisc);
if (ops->destroy)
ops->destroy(qdisc);
if (!(qdisc->flags&TCQ_F_BUILTIN))
kfree(qdisc);
}
void dev_activate(struct net_device *dev)
{
/* No queueing discipline is attached to device;
create default one i.e. pfifo_fast for devices,
which need queueing and noqueue_qdisc for
virtual interfaces
*/
if (dev->qdisc_sleeping == &noop_qdisc) {
struct Qdisc *qdisc;
if (dev->tx_queue_len) {
qdisc = qdisc_create_dflt(dev, &pfifo_fast_ops);
if (qdisc == NULL) {
printk(KERN_INFO "%s: activation failed\n", dev->name);
return;
}
} else {
qdisc = &noqueue_qdisc;
}
write_lock(&qdisc_tree_lock);
dev->qdisc_sleeping = qdisc;
write_unlock(&qdisc_tree_lock);
}
spin_lock_bh(&dev->queue_lock);
if ((dev->qdisc = dev->qdisc_sleeping) != &noqueue_qdisc) {
dev->trans_start = jiffies;
dev_watchdog_up(dev);
}
spin_unlock_bh(&dev->queue_lock);
}
void dev_deactivate(struct net_device *dev)
{
struct Qdisc *qdisc;
spin_lock_bh(&dev->queue_lock);
qdisc = dev->qdisc;
dev->qdisc = &noop_qdisc;
qdisc_reset(qdisc);
spin_unlock_bh(&dev->queue_lock);
dev_watchdog_down(dev);
while (test_bit(__LINK_STATE_SCHED, &dev->state)) {
current->policy |= SCHED_YIELD;
schedule();
}
spin_unlock_wait(&dev->xmit_lock);
}
void dev_init_scheduler(struct net_device *dev)
{
write_lock(&qdisc_tree_lock);
spin_lock_bh(&dev->queue_lock);
dev->qdisc = &noop_qdisc;
spin_unlock_bh(&dev->queue_lock);
dev->qdisc_sleeping = &noop_qdisc;
dev->qdisc_list = NULL;
write_unlock(&qdisc_tree_lock);
dev_watchdog_init(dev);
}
void dev_shutdown(struct net_device *dev)
{
struct Qdisc *qdisc;
write_lock(&qdisc_tree_lock);
spin_lock_bh(&dev->queue_lock);
qdisc = dev->qdisc_sleeping;
dev->qdisc = &noop_qdisc;
dev->qdisc_sleeping = &noop_qdisc;
qdisc_destroy(qdisc);
#if defined(CONFIG_NET_SCH_INGRESS) || defined(CONFIG_NET_SCH_INGRESS_MODULE)
if ((qdisc = dev->qdisc_ingress) != NULL) {
dev->qdisc_ingress = NULL;
qdisc_destroy(qdisc);
}
#endif
BUG_TRAP(dev->qdisc_list == NULL);
BUG_TRAP(!timer_pending(&dev->watchdog_timer));
dev->qdisc_list = NULL;
spin_unlock_bh(&dev->queue_lock);
write_unlock(&qdisc_tree_lock);
}
+3 -44
View File
@@ -40,26 +40,14 @@
#include <linux/lib.h>
#include <linux/errno.h>
#include <linux/types.h>
//#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
//#include <linux/in.h>
//#include <linux/inet.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
//#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/cache.h>
#include <linux/init.h>
//#include <linux/highmem.h>
//#include <net/ip.h>
//#include <net/protocol.h>
//#include <net/dst.h>
//#include <net/tcp.h>
//#include <net/udp.h>
//#include <net/sock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -162,7 +150,7 @@ static inline u8 *alloc_skb_data_page(struct sk_buff *skb)
list_ptr = free_list.next;
pf = list_entry(list_ptr, struct pfn_info, list);
pf->flags = 0; // owned by dom0
pf->flags = 0; /* owned by dom0 */
list_del(&pf->list);
free_pfns--;
@@ -218,14 +206,9 @@ struct sk_buff *alloc_zc_skb(unsigned int size,int gfp_mask)
if (data == NULL)
goto nodata;
// This is so that pci_map_single does the right thing in the driver.
// If you want to ever use this pointer otherwise, you need to regenerate it
// based on skb->pf.
/* A FAKE virtual address, so that pci_map_xxx dor the right thing. */
data = phys_to_virt((unsigned long)data);
/* XXX: does not include slab overhead */
skb->truesize = size + sizeof(struct sk_buff);
/* Load the data pointers. */
skb->head = data;
skb->data = data;
@@ -302,9 +285,6 @@ struct sk_buff *alloc_skb(unsigned int size,int gfp_mask)
if (data == NULL)
goto nodata;
/* XXX: does not include slab overhead */
skb->truesize = size + sizeof(struct sk_buff);
/* Load the data pointers. */
skb->head = data;
skb->data = data;
@@ -343,15 +323,9 @@ static inline void skb_headerinit(void *p, kmem_cache_t *cache,
skb->next = NULL;
skb->prev = NULL;
skb->list = NULL;
skb->sk = NULL;
skb->stamp.tv_sec=0; /* No idea about time */
skb->dev = NULL;
// skb->dst = NULL;
memset(skb->cb, 0, sizeof(skb->cb));
skb->pkt_type = PACKET_HOST; /* Default type */
skb->ip_summed = 0;
skb->priority = 0;
skb->security = 0; /* By default packets are insecure */
skb->destructor = NULL;
#ifdef CONFIG_NETFILTER
@@ -411,7 +385,7 @@ static void skb_release_data(struct sk_buff *skb)
}
else
{
BUG(); //skb_release_data called with unknown skb type!
BUG();
}
}
}
@@ -442,7 +416,6 @@ void __kfree_skb(struct sk_buff *skb)
BUG();
}
// dst_release(skb->dst);
if(skb->destructor) {
if (in_irq()) {
printk(KERN_WARNING "Warning: kfree_skb on hard IRQ %p\n",
@@ -487,26 +460,18 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
n->next = n->prev = NULL;
n->list = NULL;
n->sk = NULL;
C(stamp);
C(dev);
C(h);
C(nh);
C(mac);
// C(dst);
// dst_clone(n->dst);
memcpy(n->cb, skb->cb, sizeof(skb->cb));
C(len);
C(data_len);
C(csum);
n->cloned = 1;
C(pkt_type);
C(ip_summed);
C(priority);
atomic_set(&n->users, 1);
C(protocol);
C(security);
C(truesize);
C(head);
C(data);
C(tail);
@@ -543,20 +508,14 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
unsigned long offset = new->data - old->data;
new->list=NULL;
new->sk=NULL;
new->dev=old->dev;
new->priority=old->priority;
new->protocol=old->protocol;
// new->dst=dst_clone(old->dst);
new->h.raw=old->h.raw+offset;
new->nh.raw=old->nh.raw+offset;
new->mac.raw=old->mac.raw+offset;
memcpy(new->cb, old->cb, sizeof(old->cb));
atomic_set(&new->users, 1);
new->pkt_type=old->pkt_type;
new->stamp=old->stamp;
new->destructor = NULL;
new->security=old->security;
#ifdef CONFIG_NETFILTER
new->nfmark=old->nfmark;
new->nfcache=old->nfcache;
-75
View File
@@ -1,75 +0,0 @@
/*
* Generic address resultion entity
*
* Authors:
* net_random Alan Cox
* net_ratelimit Andy Kleen
*
* Created by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/config.h>
#include <linux/lib.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/types.h>
//#include <linux/kernel.h>
#include <linux/sched.h>
//#include <linux/string.h>
#include <linux/mm.h>
static unsigned long net_rand_seed = 152L;
unsigned long net_random(void)
{
net_rand_seed=net_rand_seed*69069L+1;
return net_rand_seed^jiffies;
}
void net_srandom(unsigned long entropy)
{
net_rand_seed ^= entropy;
net_random();
}
int net_msg_cost = 5*HZ;
int net_msg_burst = 10*5*HZ;
/*
* This enforces a rate limit: not more than one kernel message
* every 5secs to make a denial-of-service attack impossible.
*
* All warning printk()s should be guarded by this function.
*/
int net_ratelimit(void)
{
static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
static unsigned long toks = 10*5*HZ;
static unsigned long last_msg;
static int missed;
unsigned long flags;
unsigned long now = jiffies;
spin_lock_irqsave(&ratelimit_lock, flags);
toks += now - last_msg;
last_msg = now;
if (toks > net_msg_burst)
toks = net_msg_burst;
if (toks >= net_msg_cost) {
int lost = missed;
missed = 0;
toks -= net_msg_cost;
spin_unlock_irqrestore(&ratelimit_lock, flags);
if (lost)
printk(KERN_WARNING "NET: %d messages suppressed.\n", lost);
return 1;
}
missed++;
spin_unlock_irqrestore(&ratelimit_lock, flags);
return 0;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.