> On Nov 24, 2015, at 10:27 AM, Ben Pfaff <[email protected]> wrote:
> 
> On Fri, Nov 06, 2015 at 04:10:49PM -0800, Jarno Rajahalme wrote:
>> When modifying an existing datapath flow with recirculation actions,
>> the references to old (if any) recirculation actions need to be freed,
>> and references to new recirculation actions need to be stored.
>> 
>> Signed-off-by: Jarno Rajahalme <[email protected]>
>> Acked-by: Joe Stringer <[email protected]>
> 
> Our coding style calls for a new-line after "void":
>> +static void reval_op_init(struct ukey_op *op, enum reval_result result,
>> +                          struct udpif *udpif, struct udpif_key *ukey,
>> +                          struct recirc_refs *recircs,
>> +                          struct ofpbuf *odp_actions)
> 

Fixed.

> Here, it wasn't obvious to me why the logic changed from only allocating
> a recirc_id if we have a packet, to always allocating one (don't we
> still need to reuse the recirc id from a previous translation?):
> 

The separation of the packet (upcall) and no packet (revalidation) was suitable 
before we added the support for modifying datapath flows in-place, when only 
actions change. Before, when doing revalidation the produced actions were only 
used for comparison, but now they can also be used as a replacement for the old 
datapath actions. This is why we now need to allocate and hold a reference to a 
recirculation context also when revalidating. The reference will be freed if 
the actions are freed without installing them to an existing flow. Also, the 
recirc_alloc_id_ctx() will reuse existing recirculation contexts (and adding a 
reference) if possible. I’ll update the comment to mention this.

  Jarno

>> @@ -3588,30 +3588,16 @@ compose_recirculate_action__(struct xlate_ctx *ctx, 
>> uint8_t table)
>>         .ofpacts = ctx->action_set.data,
>>     };
>> 
>> -    /* Only allocate recirculation ID if we have a packet. */
>> -    if (ctx->xin->packet) {
>> -        /* Allocate a unique recirc id for the given metadata state in the
>> -         * flow.  The life-cycle of this recirc id is managed by 
>> associating it
>> -         * with the udpif key ('ukey') created for each new datapath flow. 
>> */
>> -        id = recirc_alloc_id_ctx(&state);
>> -        if (!id) {
>> -            XLATE_REPORT_ERROR(ctx, "Failed to allocate recirculation id");
>> -            ctx->error = XLATE_NO_RECIRCULATION_CONTEXT;
>> -            return;
>> -        }
>> -        xlate_out_add_recirc(ctx->xout, id);
>> -    } else {
>> -        /* Look up an existing recirc id for the given metadata state in the
>> -         * flow.  No new reference is taken, as the ID is RCU protected and 
>> is
>> -         * only required temporarily for verification.
>> -         * If flow tables have changed sufficiently this can fail and we 
>> will
>> -         * delete the old datapath flow. */
>> -        id = recirc_find_id(&state);
>> -        if (!id) {
>> -            ctx->error = XLATE_NO_RECIRCULATION_CONTEXT;
>> -            return;
>> -        }
>> +    /* Allocate a unique recirc id for the given metadata state in the
>> +     * flow.  The life-cycle of this recirc id is managed by associating it
>> +     * with the udpif key ('ukey') created for each new datapath flow. */
>> +    id = recirc_alloc_id_ctx(&state);
>> +    if (!id) {
>> +        XLATE_REPORT_ERROR(ctx, "Failed to allocate recirculation id");
>> +        ctx->error = XLATE_NO_RECIRCULATION_CONTEXT;
>> +        return;
>>     }
>> +    recirc_refs_add(&ctx->xout->recircs, id);
> 
> Thanks,
> 
> Ben.

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to