debuggers.hg

view tools/memshr/interface.c @ 22848:6341fe0f4e5a

Added tag 4.1.0-rc2 for changeset 9dca60d88c63
author Keir Fraser <keir@xen.org>
date Tue Jan 25 14:06:55 2011 +0000 (2011-01-25)
parents 779c0ef9682c
children
line source
1 /******************************************************************************
2 *
3 * Copyright (c) 2009 Citrix Systems, Inc. (Grzegorz Milos)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 #include <string.h>
20 #include <inttypes.h>
22 #include "memshr.h"
23 #include "memshr-priv.h"
24 #include "bidir-hash.h"
25 #include "shm.h"
26 #include "bidir-daemon.h"
28 typedef struct {
29 int enabled;
30 domid_t domid;
31 xc_interface *xc_handle;
32 } memshr_vbd_info_t;
34 memshr_vbd_info_t vbd_info = {0, DOMID_INVALID};
37 typedef struct {
38 struct shared_memshr_info *shared_info;
39 struct fgprtshr_hash *fgprts;
40 struct blockshr_hash *blks;
41 } private_memshr_info_t;
43 private_memshr_info_t memshr;
45 #define SHARED_INFO (memshr.shared_info)
47 void memshr_set_domid(int domid)
48 {
49 vbd_info.domid = domid;
50 }
52 void memshr_daemon_initialize(void)
53 {
54 void *shm_base_addr;
55 struct fgprtshr_hash *h;
57 memset(&memshr, 0, sizeof(private_memshr_info_t));
59 if((SHARED_INFO = shm_shared_info_open(1)) == NULL)
60 {
61 DPRINTF("Failed to init shared info.\n");
62 return;
63 }
65 if((memshr.fgprts = shm_fgprtshr_hash_open(1)) == NULL)
66 {
67 DPRINTF("Failed to init fgprtshr hash.\n");
68 return;
69 }
70 memshr.shared_info->fgprtshr_hash_inited = 1;
72 if((memshr.blks = shm_blockshr_hash_open(1)) == NULL)
73 {
74 DPRINTF("Failed to init blockshr hash.\n");
75 return;
76 }
77 memshr.shared_info->blockshr_hash_inited = 1;
79 bidir_daemon_initialize(memshr.blks);
80 }
83 void memshr_vbd_initialize(void)
84 {
85 xc_interface *xc_handle;
87 memset(&memshr, 0, sizeof(private_memshr_info_t));
89 if((SHARED_INFO = shm_shared_info_open(0)) == NULL)
90 {
91 DPRINTF("Failed to open shared info.\n");
92 return;
93 }
95 if(!SHARED_INFO->fgprtshr_hash_inited)
96 {
97 DPRINTF("fgprtshr hash not inited.\n");
98 return;
99 }
101 if((memshr.fgprts = shm_fgprtshr_hash_open(0)) == NULL)
102 {
103 DPRINTF("Failed to open fgprtshr_hash.\n");
104 return;
105 }
107 if((memshr.blks = shm_blockshr_hash_open(0)) == NULL)
108 {
109 DPRINTF("Failed to open blockshr_hash.\n");
110 return;
111 }
113 if(vbd_info.domid == DOMID_INVALID)
114 return;
116 if((xc_handle = xc_interface_open(0,0,0)) == 0)
117 {
118 DPRINTF("Failed to open XC interface.\n");
119 return;
120 }
122 vbd_info.xc_handle = xc_handle;
123 vbd_info.enabled = 1;
124 }
126 uint16_t memshr_vbd_image_get(char* file)
127 {
128 uint16_t id;
130 if(pthread_mutex_lock(&SHARED_INFO->lock)) goto error_out;
131 id = shm_vbd_image_get(file, SHARED_INFO->vbd_images);
132 if(pthread_mutex_unlock(&SHARED_INFO->lock)) goto error_out;
134 return id;
135 error_out:
136 return 0;
137 }
139 void memshr_vbd_image_put(uint16_t memshr_id)
140 {
141 if(pthread_mutex_lock(&SHARED_INFO->lock)) return;
142 shm_vbd_image_put(memshr_id, SHARED_INFO->vbd_images);
143 if(pthread_mutex_unlock(&SHARED_INFO->lock)) return;
144 }
146 int memshr_vbd_issue_ro_request(char *buf,
147 grant_ref_t gref,
148 uint16_t file_id,
149 uint64_t sec,
150 int secs,
151 uint64_t *hnd)
152 {
153 vbdblk_t blk;
154 uint64_t s_hnd, c_hnd;
155 int ret;
157 *hnd = 0;
158 if(!vbd_info.enabled)
159 return -1;
161 if(secs != 8)
162 return -2;
164 /* Nominate the granted page for sharing */
165 ret = xc_memshr_nominate_gref(vbd_info.xc_handle,
166 vbd_info.domid,
167 gref,
168 &c_hnd);
169 /* If page couldn't be made sharable, we cannot do anything about it */
170 if(ret != 0)
171 return -3;
172 *hnd = c_hnd;
174 /* Check if we've read matching disk block previously */
175 blk.sec = sec;
176 blk.disk_id = file_id;
177 if(blockshr_block_lookup(memshr.blks, blk, &s_hnd) > 0)
178 {
179 ret = xc_memshr_share(vbd_info.xc_handle, s_hnd, c_hnd);
180 if(!ret) return 0;
181 /* Handles failed to be shared => at least one of them must be invalid,
182 remove the relevant ones from the map */
183 switch(ret)
184 {
185 case XEN_DOMCTL_MEM_SHARING_S_HANDLE_INVALID:
186 ret = blockshr_shrhnd_remove(memshr.blks, s_hnd, NULL);
187 if(ret) DPRINTF("Could not rm invl s_hnd: %"PRId64"\n", s_hnd);
188 break;
189 case XEN_DOMCTL_MEM_SHARING_C_HANDLE_INVALID:
190 ret = blockshr_shrhnd_remove(memshr.blks, c_hnd, NULL);
191 if(ret) DPRINTF("Could not rm invl c_hnd: %"PRId64"\n", c_hnd);
192 break;
193 default:
194 break;
195 }
196 return -5;
197 }
199 return -4;
200 }
202 void memshr_vbd_complete_ro_request(uint64_t hnd,
203 uint16_t file_id,
204 uint64_t sec,
205 int secs)
206 {
207 vbdblk_t blk;
209 if(!vbd_info.enabled)
210 return;
212 if(secs != 8)
213 return;
215 blk.sec = sec;
216 blk.disk_id = file_id;
217 if(blockshr_insert(memshr.blks, blk, hnd) < 0)
218 DPRINTF("Could not insert block hint into hash.\n");
219 }