On Wed, Nov 19, 2025 at 01:15:18PM -0600, Daniel Jurgens wrote:
> +static int virtnet_ethtool_flow_insert(struct virtnet_ff *ff,
> +                                    struct ethtool_rx_flow_spec *fs,
> +                                    u16 curr_queue_pairs)
> +{
> +     struct virtnet_ethtool_rule *eth_rule;
> +     int err;
> +
> +     if (!ff->ff_supported)
> +             return -EOPNOTSUPP;
> +
> +     err = validate_flow_input(ff, fs, curr_queue_pairs);
> +     if (err)
> +             return err;
> +
> +     eth_rule = kzalloc(sizeof(*eth_rule), GFP_KERNEL);
> +     if (!eth_rule)
> +             return -ENOMEM;
> +
> +     err = xa_alloc(&ff->ethtool.rules, &fs->location, eth_rule,
> +                    XA_LIMIT(0, le32_to_cpu(ff->ff_caps->rules_limit) - 1),
> +                    GFP_KERNEL);
> +     if (err)
> +             goto err_rule;
> +
> +     eth_rule->flow_spec = *fs;
> +
> +     err = build_and_insert(ff, eth_rule);
> +     if (err)
> +             goto err_xa;


btw kind of inelegant that we change fs->location if build_and_insert fails.
restore it?

> +     return err;
> +
> +err_xa:
> +     xa_erase(&ff->ethtool.rules, eth_rule->flow_spec.location);
> +
> +err_rule:
> +     fs->location = RX_CLS_LOC_ANY;
> +     kfree(eth_rule);
> +
> +     return err;
> +}


Reply via email to