OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [core/] [profile.c] - Diff between revs 1278 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 1278 Rev 1765
#include <linux/config.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/ip.h>
#include <linux/ip.h>
#include <linux/inet.h>
#include <linux/inet.h>
#include <net/checksum.h>
#include <net/checksum.h>
 
 
#include <asm/processor.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/system.h>
 
 
#include <net/profile.h>
#include <net/profile.h>
 
 
#ifdef CONFIG_NET_PROFILE
#ifdef CONFIG_NET_PROFILE
 
 
atomic_t net_profile_active;
atomic_t net_profile_active;
struct timeval net_profile_adjust;
struct timeval net_profile_adjust;
 
 
NET_PROFILE_DEFINE(total);
NET_PROFILE_DEFINE(total);
 
 
struct net_profile_slot *net_profile_chain = &net_prof_total;
struct net_profile_slot *net_profile_chain = &net_prof_total;
 
 
#ifdef __alpha__
#ifdef __alpha__
__u32 alpha_lo;
__u32 alpha_lo;
long alpha_hi;
long alpha_hi;
 
 
static void alpha_tick(unsigned long);
static void alpha_tick(unsigned long);
 
 
static struct timer_list alpha_timer =
static struct timer_list alpha_timer =
        { NULL, NULL, 0, 0L, alpha_tick };
        { NULL, NULL, 0, 0L, alpha_tick };
 
 
void alpha_tick(unsigned long dummy)
void alpha_tick(unsigned long dummy)
{
{
        struct timeval dummy_stamp;
        struct timeval dummy_stamp;
        net_profile_stamp(&dummy_stamp);
        net_profile_stamp(&dummy_stamp);
        alpha_timer.expires = jiffies + 4*HZ;
        alpha_timer.expires = jiffies + 4*HZ;
        add_timer(&alpha_timer);
        add_timer(&alpha_timer);
}
}
 
 
#endif
#endif
 
 
void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved)
void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved)
{
{
        struct net_profile_slot *s;
        struct net_profile_slot *s;
 
 
        net_profile_sub(entered, leaved);
        net_profile_sub(entered, leaved);
        for (s = net_profile_chain; s; s = s->next) {
        for (s = net_profile_chain; s; s = s->next) {
                if (s->active)
                if (s->active)
                        net_profile_add(leaved, &s->irq);
                        net_profile_add(leaved, &s->irq);
        }
        }
}
}
 
 
 
 
#ifdef CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
static int profile_read_proc(char *buffer, char **start, off_t offset,
static int profile_read_proc(char *buffer, char **start, off_t offset,
                             int length, int *eof, void *data)
                             int length, int *eof, void *data)
{
{
        off_t pos=0;
        off_t pos=0;
        off_t begin=0;
        off_t begin=0;
        int len=0;
        int len=0;
        struct net_profile_slot *s;
        struct net_profile_slot *s;
 
 
        len+= sprintf(buffer, "Slot            Hits       Hi         Lo         OnIrqHi    OnIrqLo    Ufl\n");
        len+= sprintf(buffer, "Slot            Hits       Hi         Lo         OnIrqHi    OnIrqLo    Ufl\n");
 
 
        if (offset == 0) {
        if (offset == 0) {
                cli();
                cli();
                net_prof_total.active = 1;
                net_prof_total.active = 1;
                atomic_inc(&net_profile_active);
                atomic_inc(&net_profile_active);
                NET_PROFILE_LEAVE(total);
                NET_PROFILE_LEAVE(total);
                sti();
                sti();
        }
        }
        for (s = net_profile_chain; s; s = s->next) {
        for (s = net_profile_chain; s; s = s->next) {
                struct net_profile_slot tmp;
                struct net_profile_slot tmp;
 
 
                cli();
                cli();
                tmp = *s;
                tmp = *s;
 
 
                /* Wrong, but pretty close to truth */
                /* Wrong, but pretty close to truth */
 
 
                s->accumulator.tv_sec = 0;
                s->accumulator.tv_sec = 0;
                s->accumulator.tv_usec = 0;
                s->accumulator.tv_usec = 0;
                s->irq.tv_sec = 0;
                s->irq.tv_sec = 0;
                s->irq.tv_usec = 0;
                s->irq.tv_usec = 0;
                s->hits = 0;
                s->hits = 0;
                s->underflow = 0;
                s->underflow = 0;
                /* Repair active count, it is possible, only if code has a bug */
                /* Repair active count, it is possible, only if code has a bug */
                if (s->active) {
                if (s->active) {
                        s->active = 0;
                        s->active = 0;
                        atomic_dec(&net_profile_active);
                        atomic_dec(&net_profile_active);
                }
                }
                sti();
                sti();
 
 
                net_profile_sub(&tmp.irq, &tmp.accumulator);
                net_profile_sub(&tmp.irq, &tmp.accumulator);
 
 
                len += sprintf(buffer+len,"%-15s %-10d %-10ld %-10lu %-10lu %-10lu %d/%d",
                len += sprintf(buffer+len,"%-15s %-10d %-10ld %-10lu %-10lu %-10lu %d/%d",
                               tmp.id,
                               tmp.id,
                               tmp.hits,
                               tmp.hits,
                               tmp.accumulator.tv_sec,
                               tmp.accumulator.tv_sec,
                               tmp.accumulator.tv_usec,
                               tmp.accumulator.tv_usec,
                               tmp.irq.tv_sec,
                               tmp.irq.tv_sec,
                               tmp.irq.tv_usec,
                               tmp.irq.tv_usec,
                               tmp.underflow, tmp.active);
                               tmp.underflow, tmp.active);
 
 
                        buffer[len++]='\n';
                        buffer[len++]='\n';
 
 
                        pos=begin+len;
                        pos=begin+len;
                        if(pos<offset) {
                        if(pos<offset) {
                                len=0;
                                len=0;
                                begin=pos;
                                begin=pos;
                        }
                        }
                        if(pos>offset+length)
                        if(pos>offset+length)
                                goto done;
                                goto done;
        }
        }
        *eof = 1;
        *eof = 1;
 
 
done:
done:
        *start=buffer+(offset-begin);
        *start=buffer+(offset-begin);
        len-=(offset-begin);
        len-=(offset-begin);
        if(len>length)
        if(len>length)
                len=length;
                len=length;
        if (len < 0)
        if (len < 0)
                len = 0;
                len = 0;
        if (offset == 0) {
        if (offset == 0) {
                cli();
                cli();
                net_prof_total.active = 0;
                net_prof_total.active = 0;
                net_prof_total.hits = 0;
                net_prof_total.hits = 0;
                net_profile_stamp(&net_prof_total.entered);
                net_profile_stamp(&net_prof_total.entered);
                sti();
                sti();
        }
        }
        return len;
        return len;
}
}
#endif
#endif
 
 
struct iphdr whitehole_iph;
struct iphdr whitehole_iph;
int whitehole_count;
int whitehole_count;
 
 
static int whitehole_xmit(struct sk_buff *skb, struct net_device *dev)
static int whitehole_xmit(struct sk_buff *skb, struct net_device *dev)
{
{
        struct net_device_stats *stats;
        struct net_device_stats *stats;
 
 
        stats = (struct net_device_stats *)dev->priv;
        stats = (struct net_device_stats *)dev->priv;
        stats->tx_packets++;
        stats->tx_packets++;
        stats->tx_bytes+=skb->len;
        stats->tx_bytes+=skb->len;
 
 
        dev_kfree_skb(skb);
        dev_kfree_skb(skb);
        return 0;
        return 0;
}
}
 
 
static void whitehole_inject(unsigned long);
static void whitehole_inject(unsigned long);
int whitehole_init(struct net_device *dev);
int whitehole_init(struct net_device *dev);
 
 
static struct timer_list whitehole_timer =
static struct timer_list whitehole_timer =
        { NULL, NULL, 0, 0L, whitehole_inject };
        { NULL, NULL, 0, 0L, whitehole_inject };
 
 
static struct net_device whitehole_dev = {
static struct net_device whitehole_dev = {
        "whitehole", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, whitehole_init, };
        "whitehole", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, whitehole_init, };
 
 
static int whitehole_open(struct net_device *dev)
static int whitehole_open(struct net_device *dev)
{
{
        whitehole_count = 100000;
        whitehole_count = 100000;
        whitehole_timer.expires = jiffies + 5*HZ;
        whitehole_timer.expires = jiffies + 5*HZ;
        add_timer(&whitehole_timer);
        add_timer(&whitehole_timer);
        return 0;
        return 0;
}
}
 
 
static int whitehole_close(struct net_device *dev)
static int whitehole_close(struct net_device *dev)
{
{
        del_timer(&whitehole_timer);
        del_timer(&whitehole_timer);
        return 0;
        return 0;
}
}
 
 
static void whitehole_inject(unsigned long dummy)
static void whitehole_inject(unsigned long dummy)
{
{
        struct net_device_stats *stats = (struct net_device_stats *)whitehole_dev.priv;
        struct net_device_stats *stats = (struct net_device_stats *)whitehole_dev.priv;
        extern int netdev_dropping;
        extern int netdev_dropping;
 
 
        do {
        do {
                struct iphdr *iph;
                struct iphdr *iph;
                struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
                struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
                if (!skb)
                if (!skb)
                        break;
                        break;
                skb_reserve(skb, 32);
                skb_reserve(skb, 32);
                iph = (struct iphdr*)skb_put(skb, sizeof(*iph));
                iph = (struct iphdr*)skb_put(skb, sizeof(*iph));
                skb->mac.raw = ((u8*)iph) - 14;
                skb->mac.raw = ((u8*)iph) - 14;
                memcpy(iph, &whitehole_iph, sizeof(*iph));
                memcpy(iph, &whitehole_iph, sizeof(*iph));
                skb->protocol = __constant_htons(ETH_P_IP);
                skb->protocol = __constant_htons(ETH_P_IP);
                skb->dev = &whitehole_dev;
                skb->dev = &whitehole_dev;
                skb->pkt_type = PACKET_HOST;
                skb->pkt_type = PACKET_HOST;
                stats->rx_packets++;
                stats->rx_packets++;
                stats->rx_bytes += skb->len;
                stats->rx_bytes += skb->len;
                netif_rx(skb);
                netif_rx(skb);
                whitehole_count--;
                whitehole_count--;
        } while (netdev_dropping == 0 && whitehole_count>0);
        } while (netdev_dropping == 0 && whitehole_count>0);
        if (whitehole_count > 0) {
        if (whitehole_count > 0) {
                whitehole_timer.expires = jiffies + 1;
                whitehole_timer.expires = jiffies + 1;
                add_timer(&whitehole_timer);
                add_timer(&whitehole_timer);
        }
        }
}
}
 
 
static struct net_device_stats *whitehole_get_stats(struct net_device *dev)
static struct net_device_stats *whitehole_get_stats(struct net_device *dev)
{
{
        struct net_device_stats *stats = (struct net_device_stats *) dev->priv;
        struct net_device_stats *stats = (struct net_device_stats *) dev->priv;
        return stats;
        return stats;
}
}
 
 
int __init whitehole_init(struct net_device *dev)
int __init whitehole_init(struct net_device *dev)
{
{
        dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
        dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
        if (dev->priv == NULL)
        if (dev->priv == NULL)
                return -ENOBUFS;
                return -ENOBUFS;
        memset(dev->priv, 0, sizeof(struct net_device_stats));
        memset(dev->priv, 0, sizeof(struct net_device_stats));
        dev->get_stats  = whitehole_get_stats;
        dev->get_stats  = whitehole_get_stats;
        dev->hard_start_xmit = whitehole_xmit;
        dev->hard_start_xmit = whitehole_xmit;
        dev->open = whitehole_open;
        dev->open = whitehole_open;
        dev->stop = whitehole_close;
        dev->stop = whitehole_close;
        ether_setup(dev);
        ether_setup(dev);
        dev->tx_queue_len = 0;
        dev->tx_queue_len = 0;
        dev->flags |= IFF_NOARP;
        dev->flags |= IFF_NOARP;
        dev->flags &= ~(IFF_BROADCAST|IFF_MULTICAST);
        dev->flags &= ~(IFF_BROADCAST|IFF_MULTICAST);
        dev->iflink = 0;
        dev->iflink = 0;
        whitehole_iph.ihl = 5;
        whitehole_iph.ihl = 5;
        whitehole_iph.version = 4;
        whitehole_iph.version = 4;
        whitehole_iph.ttl = 2;
        whitehole_iph.ttl = 2;
        whitehole_iph.saddr = in_aton("193.233.7.21");
        whitehole_iph.saddr = in_aton("193.233.7.21");
        whitehole_iph.daddr = in_aton("193.233.7.10");
        whitehole_iph.daddr = in_aton("193.233.7.10");
        whitehole_iph.tot_len = htons(20);
        whitehole_iph.tot_len = htons(20);
        whitehole_iph.check = ip_compute_csum((void *)&whitehole_iph, 20);
        whitehole_iph.check = ip_compute_csum((void *)&whitehole_iph, 20);
        return 0;
        return 0;
}
}
 
 
int net_profile_register(struct net_profile_slot *slot)
int net_profile_register(struct net_profile_slot *slot)
{
{
        cli();
        cli();
        slot->next = net_profile_chain;
        slot->next = net_profile_chain;
        net_profile_chain = slot;
        net_profile_chain = slot;
        sti();
        sti();
        return 0;
        return 0;
}
}
 
 
int net_profile_unregister(struct net_profile_slot *slot)
int net_profile_unregister(struct net_profile_slot *slot)
{
{
        struct net_profile_slot **sp, *s;
        struct net_profile_slot **sp, *s;
 
 
        for (sp = &net_profile_chain; (s = *sp) != NULL; sp = &s->next) {
        for (sp = &net_profile_chain; (s = *sp) != NULL; sp = &s->next) {
                if (s == slot) {
                if (s == slot) {
                        cli();
                        cli();
                        *sp = s->next;
                        *sp = s->next;
                        sti();
                        sti();
                        return 0;
                        return 0;
                }
                }
        }
        }
        return -ESRCH;
        return -ESRCH;
}
}
 
 
 
 
int __init net_profile_init(void)
int __init net_profile_init(void)
{
{
        int i;
        int i;
 
 
#ifdef CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
        create_proc_read_entry("net/profile", 0, 0, profile_read_proc, NULL);
        create_proc_read_entry("net/profile", 0, 0, profile_read_proc, NULL);
#endif
#endif
 
 
        register_netdevice(&whitehole_dev);
        register_netdevice(&whitehole_dev);
 
 
        printk("Evaluating net profiler cost ...");
        printk("Evaluating net profiler cost ...");
#ifdef __alpha__
#ifdef __alpha__
        alpha_tick(0);
        alpha_tick(0);
#endif
#endif
        for (i=0; i<1024; i++) {
        for (i=0; i<1024; i++) {
                NET_PROFILE_ENTER(total);
                NET_PROFILE_ENTER(total);
                NET_PROFILE_LEAVE(total);
                NET_PROFILE_LEAVE(total);
        }
        }
        if (net_prof_total.accumulator.tv_sec) {
        if (net_prof_total.accumulator.tv_sec) {
                printk(" too high!\n");
                printk(" too high!\n");
        } else {
        } else {
                net_profile_adjust.tv_usec = net_prof_total.accumulator.tv_usec>>10;
                net_profile_adjust.tv_usec = net_prof_total.accumulator.tv_usec>>10;
                printk("%ld units\n", net_profile_adjust.tv_usec);
                printk("%ld units\n", net_profile_adjust.tv_usec);
        }
        }
        net_prof_total.hits = 0;
        net_prof_total.hits = 0;
        net_profile_stamp(&net_prof_total.entered);
        net_profile_stamp(&net_prof_total.entered);
        return 0;
        return 0;
}
}
 
 
#endif
#endif
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.