static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry) { struct sock *sk; struct k_message *purge_msg; struct sk_buff *skb; dprintk("mpoa: purge_egress_shortcut: entering\n"); if (vcc == NULL) { printk("mpoa: purge_egress_shortcut: vcc == NULL\n"); return; } skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC); if (skb == NULL) { printk("mpoa: purge_egress_shortcut: out of memory\n"); return; } skb_put(skb, sizeof(struct k_message)); memset(skb->data, 0, sizeof(struct k_message)); purge_msg = (struct k_message *)skb->data; purge_msg->type = DATA_PLANE_PURGE; if (entry != NULL) purge_msg->content.eg_info = entry->ctrl_info; atm_force_charge(vcc, skb->truesize); sk = sk_atm(vcc); skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_data_ready(sk, skb->len); dprintk("mpoa: purge_egress_shortcut: exiting:\n"); return; }
int atm_charge(struct atm_vcc *vcc,int truesize) { atm_force_charge(vcc,truesize); if (atomic_read(&vcc->sk->rmem_alloc) <= vcc->sk->rcvbuf) return 1; atm_return(vcc,truesize); atomic_inc(&vcc->stats->rx_drop); return 0; }
int atm_charge(struct atm_vcc *vcc, int truesize) { atm_force_charge(vcc, truesize); if (atomic_read(&sk_atm(vcc)->sk_rmem_alloc) <= sk_atm(vcc)->sk_rcvbuf) return 1; atm_return(vcc, truesize); atomic_inc_unchecked(&vcc->stats->rx_drop); return 0; }
static void sigd_put_skb(struct sk_buff *skb) { if (!sigd) { pr_debug("atmsvc: no signaling daemon\n"); kfree_skb(skb); return; } atm_force_charge(sigd, skb->truesize); skb_queue_tail(&sk_atm(sigd)->sk_receive_queue, skb); sk_atm(sigd)->sk_data_ready(sk_atm(sigd)); }
static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) { struct atmarp_ctrl *ctrl; struct sk_buff *skb; DPRINTK("to_atmarpd(%d)\n",type); if (!atmarpd) return -EUNATCH; skb = alloc_skb(sizeof(struct atmarp_ctrl),GFP_ATOMIC); if (!skb) return -ENOMEM; ctrl = (struct atmarp_ctrl *) skb_put(skb,sizeof(struct atmarp_ctrl)); ctrl->type = type; ctrl->itf_num = itf; ctrl->ip = ip; atm_force_charge(atmarpd,skb->truesize); skb_queue_tail(&atmarpd->sk->receive_queue,skb); wake_up(&atmarpd->sleep); return 0; }
struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, int gfp_flags) { int guess = atm_guess_pdu2truesize(pdu_size); atm_force_charge(vcc,guess); if (atomic_read(&vcc->sk->rmem_alloc) <= vcc->sk->rcvbuf) { struct sk_buff *skb = alloc_skb(pdu_size,gfp_flags); if (skb) { atomic_add(skb->truesize-guess,&vcc->sk->rmem_alloc); return skb; } } atm_return(vcc,guess); atomic_inc(&vcc->stats->rx_drop); return NULL; }
/* Remember that this function may not do things that sleep */ int msg_to_mpoad(struct k_message *mesg, struct mpoa_client *mpc) { struct sk_buff *skb; if (mpc == NULL || !mpc->mpoad_vcc) { printk("mpoa: msg_to_mpoad: mesg %d to a non-existent mpoad\n", mesg->type); return -ENXIO; } skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC); if (skb == NULL) return -ENOMEM; skb_put(skb, sizeof(struct k_message)); memcpy(skb->data, mesg, sizeof(struct k_message)); atm_force_charge(mpc->mpoad_vcc, skb->truesize); skb_queue_tail(&mpc->mpoad_vcc->sk->sk_receive_queue, skb); mpc->mpoad_vcc->sk->sk_data_ready(mpc->mpoad_vcc->sk, skb->len); return 0; }
struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc, int pdu_size, gfp_t gfp_flags) { struct sock *sk = sk_atm(vcc); int guess = SKB_TRUESIZE(pdu_size); atm_force_charge(vcc, guess); if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) { struct sk_buff *skb = alloc_skb(pdu_size, gfp_flags); if (skb) { atomic_add(skb->truesize-guess, &sk->sk_rmem_alloc); return skb; } } atm_return(vcc, guess); atomic_inc(&vcc->stats->rx_drop); return NULL; }
/* Remember that this function may not do things that sleep */ int msg_to_mpoad(struct k_message *mesg, struct mpoa_client *mpc) { struct sk_buff *skb; struct sock *sk; if (mpc == NULL || !mpc->mpoad_vcc) { pr_info("mesg %d to a non-existent mpoad\n", mesg->type); return -ENXIO; } skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC); if (skb == NULL) return -ENOMEM; skb_put(skb, sizeof(struct k_message)); skb_copy_to_linear_data(skb, mesg, sizeof(*mesg)); atm_force_charge(mpc->mpoad_vcc, skb->truesize); sk = sk_atm(mpc->mpoad_vcc); skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_data_ready(sk, skb->len); return 0; }
static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip) { struct sock *sk; struct atmarp_ctrl *ctrl; struct sk_buff *skb; DPRINTK("to_atmarpd(%d)\n", type); if (!atmarpd) return -EUNATCH; skb = alloc_skb(sizeof(struct atmarp_ctrl),GFP_ATOMIC); if (!skb) return -ENOMEM; ctrl = (struct atmarp_ctrl *) skb_put(skb,sizeof(struct atmarp_ctrl)); ctrl->type = type; ctrl->itf_num = itf; ctrl->ip = ip; atm_force_charge(atmarpd, skb->truesize); sk = sk_atm(atmarpd); skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_data_ready(sk, skb->len); return 0; }
static void sigd_put_skb(struct sk_buff *skb) { #ifdef WAIT_FOR_DEMON DECLARE_WAITQUEUE(wait,current); add_wait_queue(&sigd_sleep,&wait); while (!sigd) { set_current_state(TASK_UNINTERRUPTIBLE); pr_debug("atmsvc: waiting for signaling demon...\n"); schedule(); } current->state = TASK_RUNNING; remove_wait_queue(&sigd_sleep,&wait); #else if (!sigd) { pr_debug("atmsvc: no signaling demon\n"); kfree_skb(skb); return; } #endif atm_force_charge(sigd,skb->truesize); skb_queue_tail(&sk_atm(sigd)->sk_receive_queue,skb); sk_atm(sigd)->sk_data_ready(sk_atm(sigd), skb->len); }