ice: convert vf->vc_ops to a const pointer
authorJacob Keller <jacob.e.keller@intel.com>
Wed, 23 Feb 2022 00:26:51 +0000 (16:26 -0800)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Tue, 15 Mar 2022 00:22:58 +0000 (17:22 -0700)
The vc_ops structure is used to allow different handlers for virtchnl
commands when the driver is in representor mode. The current
implementation uses a copy of the ops table in each VF, and modifies
this copy dynamically.

The usual practice in kernel code is to store the ops table in a
constant structure and point to different versions. This has a number of
advantages:

  1. Reduced memory usage. Each VF merely points to the correct table,
     so they're able to re-use the same constant lookup table in memory.
  2. Consistency. It becomes more difficult to accidentally update or
     edit only one op call. Instead, the code switches to the correct
     able by a single pointer write. In general this is atomic, either
     the pointer is updated or its not.
  3. Code Layout. The VF structure can store a pointer to the table
     without needing to have the full structure definition defined prior
     to the VF structure definition. This will aid in future refactoring
     of code by allowing the VF pointer to be kept in ice_vf_lib.h while
     the virtchnl ops table can be maintained in ice_virtchnl.h

There is one major downside in the case of the vc_ops structure. Most of
the operations in the table are the same between the two current
implementations. This can appear to lead to duplication since each
implementation must now fill in the complete table. It could make
spotting the differences in the representor mode more challenging.
Unfortunately, methods to make this less error prone either add
complexity overhead (macros using CPP token concatenation) or don't work
on all compilers we support (constant initializer from another constant
structure).

The cost of maintaining two structures does not out weigh the benefits
of the constant table model.

While we're making these changes, go ahead and rename the structure and
implementations with "virtchnl" instead of "vc_vf_". This will more
closely align with the planned file renaming, and avoid similar names when
we later introduce a "vf ops" table for separating Scalable IOV and
Single Root IOV implementations.

Leave the accessor/assignment functions in order to avoid issues with
compiling with options disabled. The interface makes it easier to handle
when CONFIG_PCI_IOV is disabled in the kernel.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice_repr.c
drivers/net/ethernet/intel/ice/ice_sriov.c
drivers/net/ethernet/intel/ice/ice_sriov.h

index e0be276..848f2ad 100644 (file)
@@ -339,7 +339,7 @@ static int ice_repr_add(struct ice_vf *vf)
 
        devlink_port_type_eth_set(&vf->devlink_port, repr->netdev);
 
-       ice_vc_change_ops_to_repr(&vf->vc_ops);
+       ice_virtchnl_set_repr_ops(vf);
 
        return 0;
 
@@ -384,7 +384,7 @@ static void ice_repr_rem(struct ice_vf *vf)
        kfree(vf->repr);
        vf->repr = NULL;
 
-       ice_vc_set_dflt_vf_ops(&vf->vc_ops);
+       ice_virtchnl_set_dflt_ops(vf);
 }
 
 /**
index 45fe36d..8578317 100644 (file)
@@ -2023,7 +2023,7 @@ static int ice_create_vf_entries(struct ice_pf *pf, u16 num_vfs)
                ice_vf_ctrl_invalidate_vsi(vf);
                ice_vf_fdir_init(vf);
 
-               ice_vc_set_dflt_vf_ops(&vf->vc_ops);
+               ice_virtchnl_set_dflt_ops(vf);
 
                mutex_init(&vf->cfg_lock);
 
@@ -5672,7 +5672,7 @@ out:
        return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2, v_ret, NULL, 0);
 }
 
-static struct ice_vc_vf_ops ice_vc_vf_dflt_ops = {
+static const struct ice_virtchnl_ops ice_virtchnl_dflt_ops = {
        .get_ver_msg = ice_vc_get_ver_msg,
        .get_vf_res_msg = ice_vc_get_vf_res_msg,
        .reset_vf = ice_vc_reset_vf_msg,
@@ -5703,9 +5703,13 @@ static struct ice_vc_vf_ops ice_vc_vf_dflt_ops = {
        .dis_vlan_insertion_v2_msg = ice_vc_dis_vlan_insertion_v2_msg,
 };
 
-void ice_vc_set_dflt_vf_ops(struct ice_vc_vf_ops *ops)
+/**
+ * ice_virtchnl_set_dflt_ops - Switch to default virtchnl ops
+ * @vf: the VF to switch ops
+ */
+void ice_virtchnl_set_dflt_ops(struct ice_vf *vf)
 {
-       *ops = ice_vc_vf_dflt_ops;
+       vf->virtchnl_ops = &ice_virtchnl_dflt_ops;
 }
 
 /**
@@ -5838,15 +5842,44 @@ ice_vc_repr_cfg_promiscuous_mode(struct ice_vf *vf, u8 __always_unused *msg)
                                     NULL, 0);
 }
 
-void ice_vc_change_ops_to_repr(struct ice_vc_vf_ops *ops)
+static const struct ice_virtchnl_ops ice_virtchnl_repr_ops = {
+       .get_ver_msg = ice_vc_get_ver_msg,
+       .get_vf_res_msg = ice_vc_get_vf_res_msg,
+       .reset_vf = ice_vc_reset_vf_msg,
+       .add_mac_addr_msg = ice_vc_repr_add_mac,
+       .del_mac_addr_msg = ice_vc_repr_del_mac,
+       .cfg_qs_msg = ice_vc_cfg_qs_msg,
+       .ena_qs_msg = ice_vc_ena_qs_msg,
+       .dis_qs_msg = ice_vc_dis_qs_msg,
+       .request_qs_msg = ice_vc_request_qs_msg,
+       .cfg_irq_map_msg = ice_vc_cfg_irq_map_msg,
+       .config_rss_key = ice_vc_config_rss_key,
+       .config_rss_lut = ice_vc_config_rss_lut,
+       .get_stats_msg = ice_vc_get_stats_msg,
+       .cfg_promiscuous_mode_msg = ice_vc_repr_cfg_promiscuous_mode,
+       .add_vlan_msg = ice_vc_repr_add_vlan,
+       .remove_vlan_msg = ice_vc_repr_del_vlan,
+       .ena_vlan_stripping = ice_vc_repr_ena_vlan_stripping,
+       .dis_vlan_stripping = ice_vc_repr_dis_vlan_stripping,
+       .handle_rss_cfg_msg = ice_vc_handle_rss_cfg,
+       .add_fdir_fltr_msg = ice_vc_add_fdir_fltr,
+       .del_fdir_fltr_msg = ice_vc_del_fdir_fltr,
+       .get_offload_vlan_v2_caps = ice_vc_get_offload_vlan_v2_caps,
+       .add_vlan_v2_msg = ice_vc_add_vlan_v2_msg,
+       .remove_vlan_v2_msg = ice_vc_remove_vlan_v2_msg,
+       .ena_vlan_stripping_v2_msg = ice_vc_ena_vlan_stripping_v2_msg,
+       .dis_vlan_stripping_v2_msg = ice_vc_dis_vlan_stripping_v2_msg,
+       .ena_vlan_insertion_v2_msg = ice_vc_ena_vlan_insertion_v2_msg,
+       .dis_vlan_insertion_v2_msg = ice_vc_dis_vlan_insertion_v2_msg,
+};
+
+/**
+ * ice_virtchnl_set_repr_ops - Switch to representor virtchnl ops
+ * @vf: the VF to switch ops
+ */
+void ice_virtchnl_set_repr_ops(struct ice_vf *vf)
 {
-       ops->add_mac_addr_msg = ice_vc_repr_add_mac;
-       ops->del_mac_addr_msg = ice_vc_repr_del_mac;
-       ops->add_vlan_msg = ice_vc_repr_add_vlan;
-       ops->remove_vlan_msg = ice_vc_repr_del_vlan;
-       ops->ena_vlan_stripping = ice_vc_repr_ena_vlan_stripping;
-       ops->dis_vlan_stripping = ice_vc_repr_dis_vlan_stripping;
-       ops->cfg_promiscuous_mode_msg = ice_vc_repr_cfg_promiscuous_mode;
+       vf->virtchnl_ops = &ice_virtchnl_repr_ops;
 }
 
 /**
@@ -5861,8 +5894,8 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
 {
        u32 v_opcode = le32_to_cpu(event->desc.cookie_high);
        s16 vf_id = le16_to_cpu(event->desc.retval);
+       const struct ice_virtchnl_ops *ops;
        u16 msglen = event->msg_len;
-       struct ice_vc_vf_ops *ops;
        u8 *msg = event->msg_buf;
        struct ice_vf *vf = NULL;
        struct device *dev;
@@ -5883,7 +5916,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
                goto error_handler;
        }
 
-       ops = &vf->vc_ops;
+       ops = vf->virtchnl_ops;
 
        /* Perform basic checks on the msg */
        err = virtchnl_vc_validate_vf_msg(&vf->vf_ver, v_opcode, msg, msglen);
index a5ef3c4..b6951d7 100644 (file)
@@ -113,7 +113,7 @@ struct ice_mdd_vf_events {
 
 struct ice_vf;
 
-struct ice_vc_vf_ops {
+struct ice_virtchnl_ops {
        int (*get_ver_msg)(struct ice_vf *vf, u8 *msg);
        int (*get_vf_res_msg)(struct ice_vf *vf, u8 *msg);
        void (*reset_vf)(struct ice_vf *vf);
@@ -206,8 +206,7 @@ struct ice_vf {
        DECLARE_BITMAP(opcodes_allowlist, VIRTCHNL_OP_MAX);
 
        struct ice_repr *repr;
-
-       struct ice_vc_vf_ops vc_ops;
+       const struct ice_virtchnl_ops *virtchnl_ops;
 
        /* devlink port data */
        struct devlink_port devlink_port;
@@ -230,8 +229,8 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event);
 void ice_vc_notify_link_state(struct ice_pf *pf);
 void ice_vc_notify_reset(struct ice_pf *pf);
 void ice_vc_notify_vf_link_state(struct ice_vf *vf);
-void ice_vc_change_ops_to_repr(struct ice_vc_vf_ops *ops);
-void ice_vc_set_dflt_vf_ops(struct ice_vc_vf_ops *ops);
+void ice_virtchnl_set_repr_ops(struct ice_vf *vf);
+void ice_virtchnl_set_dflt_ops(struct ice_vf *vf);
 bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr);
 bool ice_reset_vf(struct ice_vf *vf, bool is_vflr);
 void ice_restore_all_vfs_msi_state(struct pci_dev *pdev);
@@ -303,8 +302,8 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) {
 static inline void ice_vc_notify_link_state(struct ice_pf *pf) { }
 static inline void ice_vc_notify_reset(struct ice_pf *pf) { }
 static inline void ice_vc_notify_vf_link_state(struct ice_vf *vf) { }
-static inline void ice_vc_change_ops_to_repr(struct ice_vc_vf_ops *ops) { }
-static inline void ice_vc_set_dflt_vf_ops(struct ice_vc_vf_ops *ops) { }
+static inline void ice_virtchnl_set_repr_ops(struct ice_vf *vf) { }
+static inline void ice_virtchnl_set_dflt_ops(struct ice_vf *vf) { }
 static inline void ice_set_vf_state_qs_dis(struct ice_vf *vf) { }
 static inline
 void ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event) { }