>> +static NTSTATUS >> +OvsCreateNewNBLsFromMultipleNBs(POVS_SWITCH_CONTEXT switchContext, >> + PNET_BUFFER_LIST *curNbl, >> + PNET_BUFFER_LIST *nextNbl) { >> + NTSTATUS status = STATUS_SUCCESS; >> + PNET_BUFFER_LIST newNbls = NULL; >> + PNET_BUFFER_LIST lastNbl = NULL; >> + PNET_BUFFER_LIST nbl = NULL; >> + POVS_BUFFER_CONTEXT bufContext = NULL; >> + BOOLEAN error = TRUE; >> + >> + do { >> + /* Decrement buffer context reference count. */ >> + bufContext = (POVS_BUFFER_CONTEXT) >> + NET_BUFFER_LIST_CONTEXT_DATA_START(*curNbl); >> + InterlockedDecrement((volatile LONG*)&bufContext->refCount); > > I am wondering why we need to decrement the ‘bufContext->refCount’ here. We > set it to 1 in OvsInitExternalNBLContext(). OvsPartialCopyToMultipleNBLs() > would increment the value by “number of NBLs created”. When you call > OvsCompleteNBL() on each of the new NBLs created, they decrement the refCount > on the parent. Pls. see the following code in OvsCompleteNBL(). There’s no > need to explicitly decrement the refCount. > > if (parent != NULL) { > ctx = (POVS_BUFFER_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(parent); > ASSERT(ctx && ctx->magic == OVS_CTX_MAGIC); > value = InterlockedDecrement((LONG volatile *)&ctx->refCount); > if (value == 0) { > return OvsCompleteNBL(context, parent, FALSE); > } > } > > SV: Shouldn't the initial NBL with multiple NBs be completed alfter all child > NBLs with single NB are completed? > That is the reason for decrementing the reference count before calling > OvsPartialCopyToMultipleNBLs().
Ok, I see what you are saying. The difference in this case compared to other cases where just call OvsPartialCopyNBL() is that, in this case we don’t forward or complete the original NBL, where as in the other case, we either forward/complete the original NBL. In this case, we create chopped up copies of the original NBL, and work off the copies rather than the original NBL. What you can do is to call OvsCompleteNBL() directly, or add it to the completion list OvsAddPktCompletionList() explicitly and that should do the trick. We should not be touching the ‘ctx->refCount’ directly. Calling OvsCompleteNBL() on the original prior to the children being processed is just fine since, OvsCompleteNBL() will return NULL. If you call OvsAddPktCompletionList() on the original, it would call into OvsCompleteNBL() which returns NULL, and we won’t call into NdisFSendNetBufferListsComplete(). When the last child gets completed using OvsCompleteNBL(), and OvsCompleteNBLIngress() takes care of calling NdisFSendNetBufferListsComplete() on the original. -- Nithin _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev