Skip to content

Commit

Permalink
devlink: Add support for creating and destroying regions
Browse files Browse the repository at this point in the history
This allows a device to register its supported address regions.
Each address region can be accessed directly for example reading
the snapshots taken of this address space.
Drivers are not limited in the name selection for different regions.
An example of a region-name can be: pci cr-space, register-space.

Signed-off-by: Alex Vesker <[email protected]>
Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
alexvesker authored and davem330 committed Jul 13, 2018
1 parent 23c9ef2 commit b16ebe9
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
22 changes: 22 additions & 0 deletions include/net/devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct devlink {
struct list_head dpipe_table_list;
struct list_head resource_list;
struct list_head param_list;
struct list_head region_list;
struct devlink_dpipe_headers *dpipe_headers;
const struct devlink_ops *ops;
struct device *dev;
Expand Down Expand Up @@ -397,6 +398,8 @@ enum devlink_param_generic_id {
.validate = _validate, \
}

struct devlink_region;

struct devlink_ops {
int (*reload)(struct devlink *devlink, struct netlink_ext_ack *extack);
int (*port_type_set)(struct devlink_port *devlink_port,
Expand Down Expand Up @@ -543,6 +546,11 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
union devlink_param_value init_val);
void devlink_param_value_changed(struct devlink *devlink, u32 param_id);
struct devlink_region *devlink_region_create(struct devlink *devlink,
const char *region_name,
u32 region_max_snapshots,
u64 region_size);
void devlink_region_destroy(struct devlink_region *region);

#else

Expand Down Expand Up @@ -770,6 +778,20 @@ devlink_param_value_changed(struct devlink *devlink, u32 param_id)
{
}

static inline struct devlink_region *
devlink_region_create(struct devlink *devlink,
const char *region_name,
u32 region_max_snapshots,
u64 region_size)
{
return NULL;
}

static inline void
devlink_region_destroy(struct devlink_region *region)
{
}

#endif

#endif /* _NET_DEVLINK_H_ */
84 changes: 84 additions & 0 deletions net/core/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,28 @@ devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
pool_type, p_tc_index);
}

struct devlink_region {
struct devlink *devlink;
struct list_head list;
const char *name;
struct list_head snapshot_list;
u32 max_snapshots;
u32 cur_snapshots;
u64 size;
};

static struct devlink_region *
devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
{
struct devlink_region *region;

list_for_each_entry(region, &devlink->region_list, list)
if (!strcmp(region->name, region_name))
return region;

return NULL;
}

#define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
#define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
#define DEVLINK_NL_FLAG_NEED_SB BIT(2)
Expand Down Expand Up @@ -3358,6 +3380,7 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
INIT_LIST_HEAD(&devlink->resource_list);
INIT_LIST_HEAD(&devlink->param_list);
INIT_LIST_HEAD(&devlink->region_list);
mutex_init(&devlink->lock);
return devlink;
}
Expand Down Expand Up @@ -4109,6 +4132,67 @@ void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
}
EXPORT_SYMBOL_GPL(devlink_param_value_changed);

/**
* devlink_region_create - create a new address region
*
* @devlink: devlink
* @region_name: region name
* @region_max_snapshots: Maximum supported number of snapshots for region
* @region_size: size of region
*/
struct devlink_region *devlink_region_create(struct devlink *devlink,
const char *region_name,
u32 region_max_snapshots,
u64 region_size)
{
struct devlink_region *region;
int err = 0;

mutex_lock(&devlink->lock);

if (devlink_region_get_by_name(devlink, region_name)) {
err = -EEXIST;
goto unlock;
}

region = kzalloc(sizeof(*region), GFP_KERNEL);
if (!region) {
err = -ENOMEM;
goto unlock;
}

region->devlink = devlink;
region->max_snapshots = region_max_snapshots;
region->name = region_name;
region->size = region_size;
INIT_LIST_HEAD(&region->snapshot_list);
list_add_tail(&region->list, &devlink->region_list);

mutex_unlock(&devlink->lock);
return region;

unlock:
mutex_unlock(&devlink->lock);
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(devlink_region_create);

/**
* devlink_region_destroy - destroy address region
*
* @region: devlink region to destroy
*/
void devlink_region_destroy(struct devlink_region *region)
{
struct devlink *devlink = region->devlink;

mutex_lock(&devlink->lock);
list_del(&region->list);
mutex_unlock(&devlink->lock);
kfree(region);
}
EXPORT_SYMBOL_GPL(devlink_region_destroy);

static int __init devlink_module_init(void)
{
return genl_register_family(&devlink_nl_family);
Expand Down

0 comments on commit b16ebe9

Please sign in to comment.