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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [core/] [profile.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1278 phoenix
#include <linux/config.h>
2
#include <linux/types.h>
3
#include <linux/kernel.h>
4
#include <linux/sched.h>
5
#include <linux/mm.h>
6
#include <linux/interrupt.h>
7
#include <linux/netdevice.h>
8
#include <linux/string.h>
9
#include <linux/skbuff.h>
10
#include <linux/proc_fs.h>
11
#include <linux/init.h>
12
#include <linux/ip.h>
13
#include <linux/inet.h>
14
#include <net/checksum.h>
15
 
16
#include <asm/processor.h>
17
#include <asm/uaccess.h>
18
#include <asm/system.h>
19
 
20
#include <net/profile.h>
21
 
22
#ifdef CONFIG_NET_PROFILE
23
 
24
atomic_t net_profile_active;
25
struct timeval net_profile_adjust;
26
 
27
NET_PROFILE_DEFINE(total);
28
 
29
struct net_profile_slot *net_profile_chain = &net_prof_total;
30
 
31
#ifdef __alpha__
32
__u32 alpha_lo;
33
long alpha_hi;
34
 
35
static void alpha_tick(unsigned long);
36
 
37
static struct timer_list alpha_timer =
38
        { NULL, NULL, 0, 0L, alpha_tick };
39
 
40
void alpha_tick(unsigned long dummy)
41
{
42
        struct timeval dummy_stamp;
43
        net_profile_stamp(&dummy_stamp);
44
        alpha_timer.expires = jiffies + 4*HZ;
45
        add_timer(&alpha_timer);
46
}
47
 
48
#endif
49
 
50
void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved)
51
{
52
        struct net_profile_slot *s;
53
 
54
        net_profile_sub(entered, leaved);
55
        for (s = net_profile_chain; s; s = s->next) {
56
                if (s->active)
57
                        net_profile_add(leaved, &s->irq);
58
        }
59
}
60
 
61
 
62
#ifdef CONFIG_PROC_FS
63
static int profile_read_proc(char *buffer, char **start, off_t offset,
64
                             int length, int *eof, void *data)
65
{
66
        off_t pos=0;
67
        off_t begin=0;
68
        int len=0;
69
        struct net_profile_slot *s;
70
 
71
        len+= sprintf(buffer, "Slot            Hits       Hi         Lo         OnIrqHi    OnIrqLo    Ufl\n");
72
 
73
        if (offset == 0) {
74
                cli();
75
                net_prof_total.active = 1;
76
                atomic_inc(&net_profile_active);
77
                NET_PROFILE_LEAVE(total);
78
                sti();
79
        }
80
        for (s = net_profile_chain; s; s = s->next) {
81
                struct net_profile_slot tmp;
82
 
83
                cli();
84
                tmp = *s;
85
 
86
                /* Wrong, but pretty close to truth */
87
 
88
                s->accumulator.tv_sec = 0;
89
                s->accumulator.tv_usec = 0;
90
                s->irq.tv_sec = 0;
91
                s->irq.tv_usec = 0;
92
                s->hits = 0;
93
                s->underflow = 0;
94
                /* Repair active count, it is possible, only if code has a bug */
95
                if (s->active) {
96
                        s->active = 0;
97
                        atomic_dec(&net_profile_active);
98
                }
99
                sti();
100
 
101
                net_profile_sub(&tmp.irq, &tmp.accumulator);
102
 
103
                len += sprintf(buffer+len,"%-15s %-10d %-10ld %-10lu %-10lu %-10lu %d/%d",
104
                               tmp.id,
105
                               tmp.hits,
106
                               tmp.accumulator.tv_sec,
107
                               tmp.accumulator.tv_usec,
108
                               tmp.irq.tv_sec,
109
                               tmp.irq.tv_usec,
110
                               tmp.underflow, tmp.active);
111
 
112
                        buffer[len++]='\n';
113
 
114
                        pos=begin+len;
115
                        if(pos<offset) {
116
                                len=0;
117
                                begin=pos;
118
                        }
119
                        if(pos>offset+length)
120
                                goto done;
121
        }
122
        *eof = 1;
123
 
124
done:
125
        *start=buffer+(offset-begin);
126
        len-=(offset-begin);
127
        if(len>length)
128
                len=length;
129
        if (len < 0)
130
                len = 0;
131
        if (offset == 0) {
132
                cli();
133
                net_prof_total.active = 0;
134
                net_prof_total.hits = 0;
135
                net_profile_stamp(&net_prof_total.entered);
136
                sti();
137
        }
138
        return len;
139
}
140
#endif
141
 
142
struct iphdr whitehole_iph;
143
int whitehole_count;
144
 
145
static int whitehole_xmit(struct sk_buff *skb, struct net_device *dev)
146
{
147
        struct net_device_stats *stats;
148
 
149
        stats = (struct net_device_stats *)dev->priv;
150
        stats->tx_packets++;
151
        stats->tx_bytes+=skb->len;
152
 
153
        dev_kfree_skb(skb);
154
        return 0;
155
}
156
 
157
static void whitehole_inject(unsigned long);
158
int whitehole_init(struct net_device *dev);
159
 
160
static struct timer_list whitehole_timer =
161
        { NULL, NULL, 0, 0L, whitehole_inject };
162
 
163
static struct net_device whitehole_dev = {
164
        "whitehole", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, whitehole_init, };
165
 
166
static int whitehole_open(struct net_device *dev)
167
{
168
        whitehole_count = 100000;
169
        whitehole_timer.expires = jiffies + 5*HZ;
170
        add_timer(&whitehole_timer);
171
        return 0;
172
}
173
 
174
static int whitehole_close(struct net_device *dev)
175
{
176
        del_timer(&whitehole_timer);
177
        return 0;
178
}
179
 
180
static void whitehole_inject(unsigned long dummy)
181
{
182
        struct net_device_stats *stats = (struct net_device_stats *)whitehole_dev.priv;
183
        extern int netdev_dropping;
184
 
185
        do {
186
                struct iphdr *iph;
187
                struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
188
                if (!skb)
189
                        break;
190
                skb_reserve(skb, 32);
191
                iph = (struct iphdr*)skb_put(skb, sizeof(*iph));
192
                skb->mac.raw = ((u8*)iph) - 14;
193
                memcpy(iph, &whitehole_iph, sizeof(*iph));
194
                skb->protocol = __constant_htons(ETH_P_IP);
195
                skb->dev = &whitehole_dev;
196
                skb->pkt_type = PACKET_HOST;
197
                stats->rx_packets++;
198
                stats->rx_bytes += skb->len;
199
                netif_rx(skb);
200
                whitehole_count--;
201
        } while (netdev_dropping == 0 && whitehole_count>0);
202
        if (whitehole_count > 0) {
203
                whitehole_timer.expires = jiffies + 1;
204
                add_timer(&whitehole_timer);
205
        }
206
}
207
 
208
static struct net_device_stats *whitehole_get_stats(struct net_device *dev)
209
{
210
        struct net_device_stats *stats = (struct net_device_stats *) dev->priv;
211
        return stats;
212
}
213
 
214
int __init whitehole_init(struct net_device *dev)
215
{
216
        dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
217
        if (dev->priv == NULL)
218
                return -ENOBUFS;
219
        memset(dev->priv, 0, sizeof(struct net_device_stats));
220
        dev->get_stats  = whitehole_get_stats;
221
        dev->hard_start_xmit = whitehole_xmit;
222
        dev->open = whitehole_open;
223
        dev->stop = whitehole_close;
224
        ether_setup(dev);
225
        dev->tx_queue_len = 0;
226
        dev->flags |= IFF_NOARP;
227
        dev->flags &= ~(IFF_BROADCAST|IFF_MULTICAST);
228
        dev->iflink = 0;
229
        whitehole_iph.ihl = 5;
230
        whitehole_iph.version = 4;
231
        whitehole_iph.ttl = 2;
232
        whitehole_iph.saddr = in_aton("193.233.7.21");
233
        whitehole_iph.daddr = in_aton("193.233.7.10");
234
        whitehole_iph.tot_len = htons(20);
235
        whitehole_iph.check = ip_compute_csum((void *)&whitehole_iph, 20);
236
        return 0;
237
}
238
 
239
int net_profile_register(struct net_profile_slot *slot)
240
{
241
        cli();
242
        slot->next = net_profile_chain;
243
        net_profile_chain = slot;
244
        sti();
245
        return 0;
246
}
247
 
248
int net_profile_unregister(struct net_profile_slot *slot)
249
{
250
        struct net_profile_slot **sp, *s;
251
 
252
        for (sp = &net_profile_chain; (s = *sp) != NULL; sp = &s->next) {
253
                if (s == slot) {
254
                        cli();
255
                        *sp = s->next;
256
                        sti();
257
                        return 0;
258
                }
259
        }
260
        return -ESRCH;
261
}
262
 
263
 
264
int __init net_profile_init(void)
265
{
266
        int i;
267
 
268
#ifdef CONFIG_PROC_FS
269
        create_proc_read_entry("net/profile", 0, 0, profile_read_proc, NULL);
270
#endif
271
 
272
        register_netdevice(&whitehole_dev);
273
 
274
        printk("Evaluating net profiler cost ...");
275
#ifdef __alpha__
276
        alpha_tick(0);
277
#endif
278
        for (i=0; i<1024; i++) {
279
                NET_PROFILE_ENTER(total);
280
                NET_PROFILE_LEAVE(total);
281
        }
282
        if (net_prof_total.accumulator.tv_sec) {
283
                printk(" too high!\n");
284
        } else {
285
                net_profile_adjust.tv_usec = net_prof_total.accumulator.tv_usec>>10;
286
                printk("%ld units\n", net_profile_adjust.tv_usec);
287
        }
288
        net_prof_total.hits = 0;
289
        net_profile_stamp(&net_prof_total.entered);
290
        return 0;
291
}
292
 
293
#endif

powered by: WebSVN 2.1.0

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