>> +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

Reply via email to