|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCHv5 12/14] xen-blkback: safely unmap grants in case they are still in use
Hello,
El 12/03/15 a les 9.08, Bob Liu ha escrit:
>
> On 03/09/2015 07:02 PM, David Vrabel wrote:
>> On 09/03/15 10:51, Bob Liu wrote:
>>>
>>> On 03/09/2015 05:30 PM, David Vrabel wrote:
>>>> On 09/03/15 09:09, Bob Liu wrote:
>>>>> Hi David,
>>>>>
>>>>> Recently I met an issue which is likely related with this patch. It
>>>>> happened when running block benchmark on domU, the backend was an iSCSI
>>>>> disk connected to dom0. I got below panic at put_page_testzero() on
>>>>> dom0, at that time the ixgbe network card was freeing skb pages in
>>>>> __skb_frag_unref() but the page->_count was already 0.
>>>>> Do you think is it possiable that page was already freed by blkback?
>>>>
>>>> It's possible, but in this case I think the blkback device must have
>>>> been destroyed for this to have happened, because blkback doesn't free
>>>> the pages until it is destroyed.
>>>>
>>>
>>> Sorry, I didn't get the point here, doesn't bio_complete free pages?
>>> E.g.
>>> __end_block_io_op() > xen_blkbk_unmap_and_respond() > put_free_pages()
>>> Then shrink_free_pagepool() free the page finally.
>>
>> Ug. That's all the persistent grant stuff I'm not very familiar with.
>> Perhaps Roger can comment?
>>
>
> Well, I think I may figure out this issue but haven't confirmed yet.
>
> In purge_persistent_gnt() > unmap_purged_grants(), we should also change
> to use gnttab_unmap_refs_async().
Good catch! Yes xen_blkbk_unmap_purged_grants is not using the new
unmap interface. I have a patch that should fix this, but right now I'm
not even able to compile test it. If you want to give it a spin:
diff --git a/drivers/block/xen-blkback/blkback.c
b/drivers/block/xen-blkback/blkback.c
index 2a04d34..cd1517f 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -327,9 +327,19 @@ void xen_blkbk_unmap_purged_grants(struct work_struct
*work)
struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
struct persistent_gnt *persistent_gnt;
- int ret, segs_to_unmap = 0;
+ int segs_to_unmap = 0;
+ struct gntab_unmap_queue_data unmap_data;
+ struct completion unmap_completion;
struct xen_blkif *blkif = container_of(work, typeof(*blkif),
persistent_purge_work);
+ init_completion(&unmap_completion);
+
+ unmap_data.data = &unmap_completion;
+ unmap_data.done = &free_persistent_gnts_unmap_callback;
+ unmap_data.pages = pages;
+ unmap_data.unmap_ops = unmap;
+ unmap_data.kunmap_ops = NULL;
+
while(!list_empty(&blkif->persistent_purge_list)) {
persistent_gnt = list_first_entry(&blkif->persistent_purge_list,
struct persistent_gnt,
@@ -343,20 +353,19 @@ void xen_blkbk_unmap_purged_grants(struct work_struct
*work)
pages[segs_to_unmap] = persistent_gnt->page;
- if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
- ret = gnttab_unmap_refs(unmap, NULL, pages,
- segs_to_unmap);
- BUG_ON(ret);
+ if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST ||
+ list_empty(&blkif->persistent_purge_list)) {
+
+ unmap_data.count = segs_to_unmap;
+ gnttab_unmap_refs_async(&unmap_data);
+ wait_for_completion(&unmap_completion);
+
put_free_pages(blkif, pages, segs_to_unmap);
segs_to_unmap = 0;
}
kfree(persistent_gnt);
}
- if (segs_to_unmap > 0) {
- ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap);
- BUG_ON(ret);
- put_free_pages(blkif, pages, segs_to_unmap);
- }
+ BUG_ON(segs_to_unmap != 0);
}
static void purge_persistent_gnt(struct xen_blkif *blkif)
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |