@@ -118,8 +118,15 @@ cdev_pager_lookup(void *handle)
118
118
{
119
119
vm_object_t object ;
120
120
121
+ again :
121
122
mtx_lock (& dev_pager_mtx );
122
123
object = vm_pager_object_lookup (& dev_pager_object_list , handle );
124
+ if (object != NULL && object -> un_pager .devp .dev == NULL ) {
125
+ msleep (& object -> un_pager .devp .dev , & dev_pager_mtx ,
126
+ PVM | PDROP , "cdplkp" , 0 );
127
+ vm_object_deallocate (object );
128
+ goto again ;
129
+ }
123
130
mtx_unlock (& dev_pager_mtx );
124
131
return (object );
125
132
}
@@ -129,9 +136,8 @@ cdev_pager_allocate(void *handle, enum obj_type tp,
129
136
const struct cdev_pager_ops * ops , vm_ooffset_t size , vm_prot_t prot ,
130
137
vm_ooffset_t foff , struct ucred * cred )
131
138
{
132
- vm_object_t object , object1 ;
139
+ vm_object_t object ;
133
140
vm_pindex_t pindex ;
134
- u_short color ;
135
141
136
142
if (tp != OBJT_DEVICE && tp != OBJT_MGTDEVICE )
137
143
return (NULL );
@@ -157,32 +163,36 @@ cdev_pager_allocate(void *handle, enum obj_type tp,
157
163
pindex < OFF_TO_IDX (size ))
158
164
return (NULL );
159
165
160
- if (ops -> cdev_pg_ctor (handle , size , prot , foff , cred , & color ) != 0 )
161
- return (NULL );
166
+ again :
162
167
mtx_lock (& dev_pager_mtx );
163
168
164
169
/*
165
170
* Look up pager, creating as necessary.
166
171
*/
167
- object1 = NULL ;
168
172
object = vm_pager_object_lookup (& dev_pager_object_list , handle );
169
173
if (object == NULL ) {
174
+ vm_object_t object1 ;
175
+
170
176
/*
171
177
* Allocate object and associate it with the pager. Initialize
172
178
* the object's pg_color based upon the physical address of the
173
179
* device's memory.
174
180
*/
175
181
mtx_unlock (& dev_pager_mtx );
176
182
object1 = vm_object_allocate (tp , pindex );
177
- object1 -> flags |= OBJ_COLORED ;
178
- object1 -> pg_color = color ;
179
- object1 -> handle = handle ;
180
- object1 -> un_pager .devp .ops = ops ;
181
- object1 -> un_pager .devp .dev = handle ;
182
- TAILQ_INIT (& object1 -> un_pager .devp .devp_pglist );
183
183
mtx_lock (& dev_pager_mtx );
184
184
object = vm_pager_object_lookup (& dev_pager_object_list , handle );
185
185
if (object != NULL ) {
186
+ object1 -> type = OBJT_DEAD ;
187
+ vm_object_deallocate (object1 );
188
+ object1 = NULL ;
189
+ if (object -> un_pager .devp .dev == NULL ) {
190
+ msleep (& object -> un_pager .devp .dev ,
191
+ & dev_pager_mtx , PVM | PDROP , "cdplkp" , 0 );
192
+ vm_object_deallocate (object );
193
+ goto again ;
194
+ }
195
+
186
196
/*
187
197
* We raced with other thread while allocating object.
188
198
*/
@@ -194,29 +204,51 @@ cdev_pager_allocate(void *handle, enum obj_type tp,
194
204
KASSERT (object -> un_pager .devp .ops == ops ,
195
205
("Inconsistent devops %p %p" , object , ops ));
196
206
} else {
207
+ u_short color ;
208
+
197
209
object = object1 ;
198
210
object1 = NULL ;
199
211
object -> handle = handle ;
212
+ object -> un_pager .devp .ops = ops ;
213
+ TAILQ_INIT (& object -> un_pager .devp .devp_pglist );
200
214
TAILQ_INSERT_TAIL (& dev_pager_object_list , object ,
201
215
pager_object_list );
216
+ mtx_unlock (& dev_pager_mtx );
202
217
if (ops -> cdev_pg_populate != NULL )
203
218
vm_object_set_flag (object , OBJ_POPULATE );
219
+ if (ops -> cdev_pg_ctor (handle , size , prot , foff ,
220
+ cred , & color ) != 0 ) {
221
+ mtx_lock (& dev_pager_mtx );
222
+ TAILQ_REMOVE (& dev_pager_object_list , object ,
223
+ pager_object_list );
224
+ wakeup (& object -> un_pager .devp .dev );
225
+ mtx_unlock (& dev_pager_mtx );
226
+ object -> type = OBJT_DEAD ;
227
+ vm_object_deallocate (object );
228
+ object = NULL ;
229
+ mtx_lock (& dev_pager_mtx );
230
+ } else {
231
+ mtx_lock (& dev_pager_mtx );
232
+ object -> flags |= OBJ_COLORED ;
233
+ object -> pg_color = color ;
234
+ object -> un_pager .devp .dev = handle ;
235
+ wakeup (& object -> un_pager .devp .dev );
236
+ }
204
237
}
238
+ MPASS (object1 == NULL );
205
239
} else {
240
+ if (object -> un_pager .devp .dev == NULL ) {
241
+ msleep (& object -> un_pager .devp .dev ,
242
+ & dev_pager_mtx , PVM | PDROP , "cdplkp" , 0 );
243
+ vm_object_deallocate (object );
244
+ goto again ;
245
+ }
206
246
if (pindex > object -> size )
207
247
object -> size = pindex ;
208
248
KASSERT (object -> type == tp ,
209
249
("Inconsistent device pager type %p %d" , object , tp ));
210
250
}
211
251
mtx_unlock (& dev_pager_mtx );
212
- if (object1 != NULL ) {
213
- object1 -> handle = object1 ;
214
- mtx_lock (& dev_pager_mtx );
215
- TAILQ_INSERT_TAIL (& dev_pager_object_list , object1 ,
216
- pager_object_list );
217
- mtx_unlock (& dev_pager_mtx );
218
- vm_object_deallocate (object1 );
219
- }
220
252
return (object );
221
253
}
222
254
0 commit comments