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