Loading drivers/net/team/team.c +38 −17 Original line number Original line Diff line number Diff line Loading @@ -371,13 +371,18 @@ static int team_option_set(struct team *team, static LIST_HEAD(mode_list); static LIST_HEAD(mode_list); static DEFINE_SPINLOCK(mode_list_lock); static DEFINE_SPINLOCK(mode_list_lock); static struct team_mode *__find_mode(const char *kind) struct team_mode_item { struct list_head list; const struct team_mode *mode; }; static struct team_mode_item *__find_mode(const char *kind) { { struct team_mode *mode; struct team_mode_item *mitem; list_for_each_entry(mode, &mode_list, list) { list_for_each_entry(mitem, &mode_list, list) { if (strcmp(mode->kind, kind) == 0) if (strcmp(mitem->mode->kind, kind) == 0) return mode; return mitem; } } return NULL; return NULL; } } Loading @@ -392,49 +397,65 @@ static bool is_good_mode_name(const char *name) return true; return true; } } int team_mode_register(struct team_mode *mode) int team_mode_register(const struct team_mode *mode) { { int err = 0; int err = 0; struct team_mode_item *mitem; if (!is_good_mode_name(mode->kind) || if (!is_good_mode_name(mode->kind) || mode->priv_size > TEAM_MODE_PRIV_SIZE) mode->priv_size > TEAM_MODE_PRIV_SIZE) return -EINVAL; return -EINVAL; mitem = kmalloc(sizeof(*mitem), GFP_KERNEL); if (!mitem) return -ENOMEM; spin_lock(&mode_list_lock); spin_lock(&mode_list_lock); if (__find_mode(mode->kind)) { if (__find_mode(mode->kind)) { err = -EEXIST; err = -EEXIST; kfree(mitem); goto unlock; goto unlock; } } list_add_tail(&mode->list, &mode_list); mitem->mode = mode; list_add_tail(&mitem->list, &mode_list); unlock: unlock: spin_unlock(&mode_list_lock); spin_unlock(&mode_list_lock); return err; return err; } } EXPORT_SYMBOL(team_mode_register); EXPORT_SYMBOL(team_mode_register); int team_mode_unregister(struct team_mode *mode) void team_mode_unregister(const struct team_mode *mode) { { struct team_mode_item *mitem; spin_lock(&mode_list_lock); spin_lock(&mode_list_lock); list_del_init(&mode->list); mitem = __find_mode(mode->kind); if (mitem) { list_del_init(&mitem->list); kfree(mitem); } spin_unlock(&mode_list_lock); spin_unlock(&mode_list_lock); return 0; } } EXPORT_SYMBOL(team_mode_unregister); EXPORT_SYMBOL(team_mode_unregister); static struct team_mode *team_mode_get(const char *kind) static const struct team_mode *team_mode_get(const char *kind) { { struct team_mode *mode; struct team_mode_item *mitem; const struct team_mode *mode = NULL; spin_lock(&mode_list_lock); spin_lock(&mode_list_lock); mode = __find_mode(kind); mitem = __find_mode(kind); if (!mode) { if (!mitem) { spin_unlock(&mode_list_lock); spin_unlock(&mode_list_lock); request_module("team-mode-%s", kind); request_module("team-mode-%s", kind); spin_lock(&mode_list_lock); spin_lock(&mode_list_lock); mode = __find_mode(kind); mitem = __find_mode(kind); } } if (mode) if (mitem) { mode = mitem->mode; if (!try_module_get(mode->owner)) if (!try_module_get(mode->owner)) mode = NULL; mode = NULL; } spin_unlock(&mode_list_lock); spin_unlock(&mode_list_lock); return mode; return mode; Loading Loading @@ -523,7 +544,7 @@ static int __team_change_mode(struct team *team, static int team_change_mode(struct team *team, const char *kind) static int team_change_mode(struct team *team, const char *kind) { { struct team_mode *new_mode; const struct team_mode *new_mode; struct net_device *dev = team->dev; struct net_device *dev = team->dev; int err; int err; Loading drivers/net/team/team_mode_activebackup.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -108,7 +108,7 @@ static const struct team_mode_ops ab_mode_ops = { .port_leave = ab_port_leave, .port_leave = ab_port_leave, }; }; static struct team_mode ab_mode = { static const struct team_mode ab_mode = { .kind = "activebackup", .kind = "activebackup", .owner = THIS_MODULE, .owner = THIS_MODULE, .priv_size = sizeof(struct ab_priv), .priv_size = sizeof(struct ab_priv), Loading drivers/net/team/team_mode_loadbalance.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -148,7 +148,7 @@ static const struct team_mode_ops lb_mode_ops = { .transmit = lb_transmit, .transmit = lb_transmit, }; }; static struct team_mode lb_mode = { static const struct team_mode lb_mode = { .kind = "loadbalance", .kind = "loadbalance", .owner = THIS_MODULE, .owner = THIS_MODULE, .priv_size = sizeof(struct lb_priv), .priv_size = sizeof(struct lb_priv), Loading drivers/net/team/team_mode_roundrobin.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -81,7 +81,7 @@ static const struct team_mode_ops rr_mode_ops = { .port_change_mac = rr_port_change_mac, .port_change_mac = rr_port_change_mac, }; }; static struct team_mode rr_mode = { static const struct team_mode rr_mode = { .kind = "roundrobin", .kind = "roundrobin", .owner = THIS_MODULE, .owner = THIS_MODULE, .priv_size = sizeof(struct rr_priv), .priv_size = sizeof(struct rr_priv), Loading include/linux/if_team.h +2 −3 Original line number Original line Diff line number Diff line Loading @@ -105,7 +105,6 @@ struct team_option { }; }; struct team_mode { struct team_mode { struct list_head list; const char *kind; const char *kind; struct module *owner; struct module *owner; size_t priv_size; size_t priv_size; Loading Loading @@ -178,8 +177,8 @@ extern int team_options_register(struct team *team, extern void team_options_unregister(struct team *team, extern void team_options_unregister(struct team *team, const struct team_option *option, const struct team_option *option, size_t option_count); size_t option_count); extern int team_mode_register(struct team_mode *mode); extern int team_mode_register(const struct team_mode *mode); extern int team_mode_unregister(struct team_mode *mode); extern void team_mode_unregister(const struct team_mode *mode); #endif /* __KERNEL__ */ #endif /* __KERNEL__ */ Loading Loading
drivers/net/team/team.c +38 −17 Original line number Original line Diff line number Diff line Loading @@ -371,13 +371,18 @@ static int team_option_set(struct team *team, static LIST_HEAD(mode_list); static LIST_HEAD(mode_list); static DEFINE_SPINLOCK(mode_list_lock); static DEFINE_SPINLOCK(mode_list_lock); static struct team_mode *__find_mode(const char *kind) struct team_mode_item { struct list_head list; const struct team_mode *mode; }; static struct team_mode_item *__find_mode(const char *kind) { { struct team_mode *mode; struct team_mode_item *mitem; list_for_each_entry(mode, &mode_list, list) { list_for_each_entry(mitem, &mode_list, list) { if (strcmp(mode->kind, kind) == 0) if (strcmp(mitem->mode->kind, kind) == 0) return mode; return mitem; } } return NULL; return NULL; } } Loading @@ -392,49 +397,65 @@ static bool is_good_mode_name(const char *name) return true; return true; } } int team_mode_register(struct team_mode *mode) int team_mode_register(const struct team_mode *mode) { { int err = 0; int err = 0; struct team_mode_item *mitem; if (!is_good_mode_name(mode->kind) || if (!is_good_mode_name(mode->kind) || mode->priv_size > TEAM_MODE_PRIV_SIZE) mode->priv_size > TEAM_MODE_PRIV_SIZE) return -EINVAL; return -EINVAL; mitem = kmalloc(sizeof(*mitem), GFP_KERNEL); if (!mitem) return -ENOMEM; spin_lock(&mode_list_lock); spin_lock(&mode_list_lock); if (__find_mode(mode->kind)) { if (__find_mode(mode->kind)) { err = -EEXIST; err = -EEXIST; kfree(mitem); goto unlock; goto unlock; } } list_add_tail(&mode->list, &mode_list); mitem->mode = mode; list_add_tail(&mitem->list, &mode_list); unlock: unlock: spin_unlock(&mode_list_lock); spin_unlock(&mode_list_lock); return err; return err; } } EXPORT_SYMBOL(team_mode_register); EXPORT_SYMBOL(team_mode_register); int team_mode_unregister(struct team_mode *mode) void team_mode_unregister(const struct team_mode *mode) { { struct team_mode_item *mitem; spin_lock(&mode_list_lock); spin_lock(&mode_list_lock); list_del_init(&mode->list); mitem = __find_mode(mode->kind); if (mitem) { list_del_init(&mitem->list); kfree(mitem); } spin_unlock(&mode_list_lock); spin_unlock(&mode_list_lock); return 0; } } EXPORT_SYMBOL(team_mode_unregister); EXPORT_SYMBOL(team_mode_unregister); static struct team_mode *team_mode_get(const char *kind) static const struct team_mode *team_mode_get(const char *kind) { { struct team_mode *mode; struct team_mode_item *mitem; const struct team_mode *mode = NULL; spin_lock(&mode_list_lock); spin_lock(&mode_list_lock); mode = __find_mode(kind); mitem = __find_mode(kind); if (!mode) { if (!mitem) { spin_unlock(&mode_list_lock); spin_unlock(&mode_list_lock); request_module("team-mode-%s", kind); request_module("team-mode-%s", kind); spin_lock(&mode_list_lock); spin_lock(&mode_list_lock); mode = __find_mode(kind); mitem = __find_mode(kind); } } if (mode) if (mitem) { mode = mitem->mode; if (!try_module_get(mode->owner)) if (!try_module_get(mode->owner)) mode = NULL; mode = NULL; } spin_unlock(&mode_list_lock); spin_unlock(&mode_list_lock); return mode; return mode; Loading Loading @@ -523,7 +544,7 @@ static int __team_change_mode(struct team *team, static int team_change_mode(struct team *team, const char *kind) static int team_change_mode(struct team *team, const char *kind) { { struct team_mode *new_mode; const struct team_mode *new_mode; struct net_device *dev = team->dev; struct net_device *dev = team->dev; int err; int err; Loading
drivers/net/team/team_mode_activebackup.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -108,7 +108,7 @@ static const struct team_mode_ops ab_mode_ops = { .port_leave = ab_port_leave, .port_leave = ab_port_leave, }; }; static struct team_mode ab_mode = { static const struct team_mode ab_mode = { .kind = "activebackup", .kind = "activebackup", .owner = THIS_MODULE, .owner = THIS_MODULE, .priv_size = sizeof(struct ab_priv), .priv_size = sizeof(struct ab_priv), Loading
drivers/net/team/team_mode_loadbalance.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -148,7 +148,7 @@ static const struct team_mode_ops lb_mode_ops = { .transmit = lb_transmit, .transmit = lb_transmit, }; }; static struct team_mode lb_mode = { static const struct team_mode lb_mode = { .kind = "loadbalance", .kind = "loadbalance", .owner = THIS_MODULE, .owner = THIS_MODULE, .priv_size = sizeof(struct lb_priv), .priv_size = sizeof(struct lb_priv), Loading
drivers/net/team/team_mode_roundrobin.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -81,7 +81,7 @@ static const struct team_mode_ops rr_mode_ops = { .port_change_mac = rr_port_change_mac, .port_change_mac = rr_port_change_mac, }; }; static struct team_mode rr_mode = { static const struct team_mode rr_mode = { .kind = "roundrobin", .kind = "roundrobin", .owner = THIS_MODULE, .owner = THIS_MODULE, .priv_size = sizeof(struct rr_priv), .priv_size = sizeof(struct rr_priv), Loading
include/linux/if_team.h +2 −3 Original line number Original line Diff line number Diff line Loading @@ -105,7 +105,6 @@ struct team_option { }; }; struct team_mode { struct team_mode { struct list_head list; const char *kind; const char *kind; struct module *owner; struct module *owner; size_t priv_size; size_t priv_size; Loading Loading @@ -178,8 +177,8 @@ extern int team_options_register(struct team *team, extern void team_options_unregister(struct team *team, extern void team_options_unregister(struct team *team, const struct team_option *option, const struct team_option *option, size_t option_count); size_t option_count); extern int team_mode_register(struct team_mode *mode); extern int team_mode_register(const struct team_mode *mode); extern int team_mode_unregister(struct team_mode *mode); extern void team_mode_unregister(const struct team_mode *mode); #endif /* __KERNEL__ */ #endif /* __KERNEL__ */ Loading