1 #include "kvm/uip.h"
2
3 #include <linux/kernel.h>
4 #include <linux/list.h>
5
uip_buf_get_used(struct uip_info * info)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.mutex);
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
uip_buf_get_free(struct uip_info * info)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.mutex);
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
uip_buf_set_used(struct uip_info * info,struct uip_buf * buf)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
uip_buf_set_free(struct uip_info * info,struct uip_buf * buf)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
uip_buf_clone(struct uip_tx_arg * arg)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