1*26570aafSAsias He #include "kvm/uip.h" 2*26570aafSAsias He 3*26570aafSAsias He #include <linux/kernel.h> 4*26570aafSAsias He #include <linux/list.h> 5*26570aafSAsias He 6*26570aafSAsias He struct uip_buf *uip_buf_get_used(struct uip_info *info) 7*26570aafSAsias He { 8*26570aafSAsias He struct uip_buf *buf; 9*26570aafSAsias He bool found = false; 10*26570aafSAsias He 11*26570aafSAsias He mutex_lock(&info->buf_lock); 12*26570aafSAsias He 13*26570aafSAsias He while (!(info->buf_used_nr > 0)) 14*26570aafSAsias He pthread_cond_wait(&info->buf_used_cond, &info->buf_lock); 15*26570aafSAsias He 16*26570aafSAsias He list_for_each_entry(buf, &info->buf_head, list) { 17*26570aafSAsias He if (buf->status == UIP_BUF_STATUS_USED) { 18*26570aafSAsias He /* 19*26570aafSAsias He * Set status to INUSE immediately to prevent 20*26570aafSAsias He * someone from using this buf until we free it 21*26570aafSAsias He */ 22*26570aafSAsias He buf->status = UIP_BUF_STATUS_INUSE; 23*26570aafSAsias He info->buf_used_nr--; 24*26570aafSAsias He found = true; 25*26570aafSAsias He break; 26*26570aafSAsias He } 27*26570aafSAsias He } 28*26570aafSAsias He 29*26570aafSAsias He mutex_unlock(&info->buf_lock); 30*26570aafSAsias He 31*26570aafSAsias He return found ? buf : NULL; 32*26570aafSAsias He } 33*26570aafSAsias He 34*26570aafSAsias He struct uip_buf *uip_buf_get_free(struct uip_info *info) 35*26570aafSAsias He { 36*26570aafSAsias He struct uip_buf *buf; 37*26570aafSAsias He bool found = false; 38*26570aafSAsias He 39*26570aafSAsias He mutex_lock(&info->buf_lock); 40*26570aafSAsias He 41*26570aafSAsias He while (!(info->buf_free_nr > 0)) 42*26570aafSAsias He pthread_cond_wait(&info->buf_free_cond, &info->buf_lock); 43*26570aafSAsias He 44*26570aafSAsias He list_for_each_entry(buf, &info->buf_head, list) { 45*26570aafSAsias He if (buf->status == UIP_BUF_STATUS_FREE) { 46*26570aafSAsias He /* 47*26570aafSAsias He * Set status to INUSE immediately to prevent 48*26570aafSAsias He * someone from using this buf until we free it 49*26570aafSAsias He */ 50*26570aafSAsias He buf->status = UIP_BUF_STATUS_INUSE; 51*26570aafSAsias He info->buf_free_nr--; 52*26570aafSAsias He found = true; 53*26570aafSAsias He break; 54*26570aafSAsias He } 55*26570aafSAsias He } 56*26570aafSAsias He 57*26570aafSAsias He mutex_unlock(&info->buf_lock); 58*26570aafSAsias He 59*26570aafSAsias He return found ? buf : NULL; 60*26570aafSAsias He } 61*26570aafSAsias He 62*26570aafSAsias He struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf) 63*26570aafSAsias He { 64*26570aafSAsias He mutex_lock(&info->buf_lock); 65*26570aafSAsias He 66*26570aafSAsias He buf->status = UIP_BUF_STATUS_USED; 67*26570aafSAsias He info->buf_used_nr++; 68*26570aafSAsias He pthread_cond_signal(&info->buf_used_cond); 69*26570aafSAsias He 70*26570aafSAsias He mutex_unlock(&info->buf_lock); 71*26570aafSAsias He 72*26570aafSAsias He return buf; 73*26570aafSAsias He } 74*26570aafSAsias He 75*26570aafSAsias He struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf) 76*26570aafSAsias He { 77*26570aafSAsias He mutex_lock(&info->buf_lock); 78*26570aafSAsias He 79*26570aafSAsias He buf->status = UIP_BUF_STATUS_FREE; 80*26570aafSAsias He info->buf_free_nr++; 81*26570aafSAsias He pthread_cond_signal(&info->buf_free_cond); 82*26570aafSAsias He 83*26570aafSAsias He mutex_unlock(&info->buf_lock); 84*26570aafSAsias He 85*26570aafSAsias He return buf; 86*26570aafSAsias He } 87*26570aafSAsias He 88*26570aafSAsias He struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg) 89*26570aafSAsias He { 90*26570aafSAsias He struct uip_buf *buf; 91*26570aafSAsias He struct uip_eth *eth2; 92*26570aafSAsias He struct uip_info *info; 93*26570aafSAsias He 94*26570aafSAsias He info = arg->info; 95*26570aafSAsias He 96*26570aafSAsias He /* 97*26570aafSAsias He * Get buffer from device to guest 98*26570aafSAsias He */ 99*26570aafSAsias He buf = uip_buf_get_free(info); 100*26570aafSAsias He 101*26570aafSAsias He /* 102*26570aafSAsias He * Clone buffer 103*26570aafSAsias He */ 104*26570aafSAsias He memcpy(buf->vnet, arg->vnet, arg->vnet_len); 105*26570aafSAsias He memcpy(buf->eth, arg->eth, arg->eth_len); 106*26570aafSAsias He buf->vnet_len = arg->vnet_len; 107*26570aafSAsias He buf->eth_len = arg->eth_len; 108*26570aafSAsias He 109*26570aafSAsias He eth2 = (struct uip_eth *)buf->eth; 110*26570aafSAsias He eth2->src = info->host_mac; 111*26570aafSAsias He eth2->dst = arg->eth->src; 112*26570aafSAsias He 113*26570aafSAsias He return buf; 114*26570aafSAsias He } 115