static void ipmr_expire_process(unsigned long dummy) { if (!spin_trylock(&mfc_unres_lock)) { mod_timer(&ipmr_expire_timer, jiffies + 1); return; } if (atomic_read(&cache_resolve_queue_len)) ipmr_do_expire_process(dummy); spin_unlock(&mfc_unres_lock); }
static void ipmr_expire_process(unsigned long dummy) { if (!spin_trylock(&mfc_unres_lock)) { mod_timer(&ipmr_expire_timer, jiffies + 1); return; } if (mfc_unres_queue != NULL) ipmr_do_expire_process(dummy); spin_unlock(&mfc_unres_lock); }
static int ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) { int err; struct mfc6_cache *c; spin_lock_bh(&mfc_unres_lock); for (c = mfc_unres_queue; c; c = c->next) { if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) && ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) break; } if (c == NULL) { /* * Create a new entry if allowable */ if (atomic_read(&cache_resolve_queue_len) >= 10 || (c = ip6mr_cache_alloc_unres()) == NULL) { spin_unlock_bh(&mfc_unres_lock); kfree_skb(skb); return -ENOBUFS; } /* * Fill in the new cache entry */ c->mf6c_parent = -1; c->mf6c_origin = ipv6_hdr(skb)->saddr; c->mf6c_mcastgrp = ipv6_hdr(skb)->daddr; /* * Reflect first query at pim6sd */ if ((err = ip6mr_cache_report(skb, mifi, MRT6MSG_NOCACHE)) < 0) { /* If the report failed throw the cache entry out - Brad Parker */ spin_unlock_bh(&mfc_unres_lock); kmem_cache_free(mrt_cachep, c); kfree_skb(skb); return err; } atomic_inc(&cache_resolve_queue_len); c->next = mfc_unres_queue; mfc_unres_queue = c; ipmr_do_expire_process(1); } /* * See if we can append the packet */ if (c->mfc_un.unres.unresolved.qlen > 3) { kfree_skb(skb); err = -ENOBUFS; } else { skb_queue_tail(&c->mfc_un.unres.unresolved, skb); err = 0; } spin_unlock_bh(&mfc_unres_lock); return err; }