|
@@ -1013,13 +1013,38 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
|
|
|
}
|
|
|
/* Add the persistent grant into the list of free grants */
|
|
|
for (i = 0; i < nseg; i++) {
|
|
|
- list_add(&s->grants_used[i]->node, &info->persistent_gnts);
|
|
|
- info->persistent_gnts_c++;
|
|
|
+ if (gnttab_query_foreign_access(s->grants_used[i]->gref)) {
|
|
|
+ /*
|
|
|
+ * If the grant is still mapped by the backend (the
|
|
|
+ * backend has chosen to make this grant persistent)
|
|
|
+ * we add it at the head of the list, so it will be
|
|
|
+ * reused first.
|
|
|
+ */
|
|
|
+ list_add(&s->grants_used[i]->node, &info->persistent_gnts);
|
|
|
+ info->persistent_gnts_c++;
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * If the grant is not mapped by the backend we end the
|
|
|
+ * foreign access and add it to the tail of the list,
|
|
|
+ * so it will not be picked again unless we run out of
|
|
|
+ * persistent grants.
|
|
|
+ */
|
|
|
+ gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
|
|
|
+ s->grants_used[i]->gref = GRANT_INVALID_REF;
|
|
|
+ list_add_tail(&s->grants_used[i]->node, &info->persistent_gnts);
|
|
|
+ }
|
|
|
}
|
|
|
if (s->req.operation == BLKIF_OP_INDIRECT) {
|
|
|
for (i = 0; i < INDIRECT_GREFS(nseg); i++) {
|
|
|
- list_add(&s->indirect_grants[i]->node, &info->persistent_gnts);
|
|
|
- info->persistent_gnts_c++;
|
|
|
+ if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) {
|
|
|
+ list_add(&s->indirect_grants[i]->node, &info->persistent_gnts);
|
|
|
+ info->persistent_gnts_c++;
|
|
|
+ } else {
|
|
|
+ gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL);
|
|
|
+ s->indirect_grants[i]->gref = GRANT_INVALID_REF;
|
|
|
+ list_add_tail(&s->indirect_grants[i]->node,
|
|
|
+ &info->persistent_gnts);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|