patch-2.3.6 linux/net/sched/police.c
Next file: linux/net/sched/sch_api.c
Previous file: linux/net/sched/estimator.c
Back to the patch index
Back to the overall index
- Lines: 97
- Date:
Wed Jun 9 14:45:37 1999
- Orig file:
v2.3.5/linux/net/sched/police.c
- Orig date:
Sun Mar 21 07:22:00 1999
diff -u --recursive --new-file v2.3.5/linux/net/sched/police.c linux/net/sched/police.c
@@ -38,6 +38,10 @@
static u32 idx_gen;
static struct tcf_police *tcf_police_ht[16];
+/* Policer hash table lock */
+static rwlock_t police_lock = RW_LOCK_UNLOCKED;
+
+/* Each policer is serialized by its individual spinlock */
static __inline__ unsigned tcf_police_hash(u32 index)
{
@@ -48,11 +52,13 @@
{
struct tcf_police *p;
+ read_lock(&police_lock);
for (p = tcf_police_ht[tcf_police_hash(index)]; p; p = p->next) {
if (p->index == index)
- return p;
+ break;
}
- return NULL;
+ read_unlock(&police_lock);
+ return p;
}
static __inline__ u32 tcf_police_new_index(void)
@@ -73,7 +79,9 @@
for (p1p = &tcf_police_ht[h]; *p1p; p1p = &(*p1p)->next) {
if (*p1p == p) {
+ write_lock_bh(&police_lock);
*p1p = p->next;
+ write_unlock_bh(&police_lock);
#ifdef CONFIG_NET_ESTIMATOR
qdisc_kill_estimator(&p->stats);
#endif
@@ -114,6 +122,8 @@
memset(p, 0, sizeof(*p));
p->refcnt = 1;
+ spin_lock_init(&p->lock);
+ p->stats.lock = &p->lock;
if (parm->rate.rate) {
if ((p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1])) == NULL)
goto failure;
@@ -144,8 +154,10 @@
qdisc_new_estimator(&p->stats, est);
#endif
h = tcf_police_hash(p->index);
+ write_lock_bh(&police_lock);
p->next = tcf_police_ht[h];
tcf_police_ht[h] = p;
+ write_unlock_bh(&police_lock);
return p;
failure:
@@ -161,19 +173,24 @@
long toks;
long ptoks = 0;
+ spin_lock(&p->lock);
+
p->stats.bytes += skb->len;
p->stats.packets++;
#ifdef CONFIG_NET_ESTIMATOR
if (p->ewma_rate && p->stats.bps >= p->ewma_rate) {
p->stats.overlimits++;
+ spin_unlock(&p->lock);
return p->action;
}
#endif
if (skb->len <= p->mtu) {
- if (p->R_tab == NULL)
+ if (p->R_tab == NULL) {
+ spin_unlock(&p->lock);
return p->result;
+ }
PSCHED_GET_TIME(now);
@@ -194,11 +211,13 @@
p->t_c = now;
p->toks = toks;
p->ptoks = ptoks;
+ spin_unlock(&p->lock);
return p->result;
}
}
p->stats.overlimits++;
+ spin_unlock(&p->lock);
return p->action;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)