net: sched: push ops lookup bits into tcf_proto_lookup_ops()
Push all bits that take care of ops lookup, including module loading outside tcf_proto_create() function, into tcf_proto_lookup_ops() Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d3585edf87
commit
f34e8bff58
@ -39,7 +39,7 @@ static DEFINE_RWLOCK(cls_mod_lock);
|
|||||||
|
|
||||||
/* Find classifier type by string name */
|
/* Find classifier type by string name */
|
||||||
|
|
||||||
static const struct tcf_proto_ops *tcf_proto_lookup_ops(const char *kind)
|
static const struct tcf_proto_ops *__tcf_proto_lookup_ops(const char *kind)
|
||||||
{
|
{
|
||||||
const struct tcf_proto_ops *t, *res = NULL;
|
const struct tcf_proto_ops *t, *res = NULL;
|
||||||
|
|
||||||
@ -57,6 +57,33 @@ static const struct tcf_proto_ops *tcf_proto_lookup_ops(const char *kind)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct tcf_proto_ops *
|
||||||
|
tcf_proto_lookup_ops(const char *kind, struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
const struct tcf_proto_ops *ops;
|
||||||
|
|
||||||
|
ops = __tcf_proto_lookup_ops(kind);
|
||||||
|
if (ops)
|
||||||
|
return ops;
|
||||||
|
#ifdef CONFIG_MODULES
|
||||||
|
rtnl_unlock();
|
||||||
|
request_module("cls_%s", kind);
|
||||||
|
rtnl_lock();
|
||||||
|
ops = __tcf_proto_lookup_ops(kind);
|
||||||
|
/* We dropped the RTNL semaphore in order to perform
|
||||||
|
* the module load. So, even if we succeeded in loading
|
||||||
|
* the module we have to replay the request. We indicate
|
||||||
|
* this using -EAGAIN.
|
||||||
|
*/
|
||||||
|
if (ops) {
|
||||||
|
module_put(ops->owner);
|
||||||
|
return ERR_PTR(-EAGAIN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
NL_SET_ERR_MSG(extack, "TC classifier not found");
|
||||||
|
return ERR_PTR(-ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Register(unregister) new classifier type */
|
/* Register(unregister) new classifier type */
|
||||||
|
|
||||||
int register_tcf_proto_ops(struct tcf_proto_ops *ops)
|
int register_tcf_proto_ops(struct tcf_proto_ops *ops)
|
||||||
@ -133,27 +160,9 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol,
|
|||||||
if (!tp)
|
if (!tp)
|
||||||
return ERR_PTR(-ENOBUFS);
|
return ERR_PTR(-ENOBUFS);
|
||||||
|
|
||||||
err = -ENOENT;
|
tp->ops = tcf_proto_lookup_ops(kind, extack);
|
||||||
tp->ops = tcf_proto_lookup_ops(kind);
|
if (IS_ERR(tp->ops)) {
|
||||||
if (!tp->ops) {
|
err = PTR_ERR(tp->ops);
|
||||||
#ifdef CONFIG_MODULES
|
|
||||||
rtnl_unlock();
|
|
||||||
request_module("cls_%s", kind);
|
|
||||||
rtnl_lock();
|
|
||||||
tp->ops = tcf_proto_lookup_ops(kind);
|
|
||||||
/* We dropped the RTNL semaphore in order to perform
|
|
||||||
* the module load. So, even if we succeeded in loading
|
|
||||||
* the module we have to replay the request. We indicate
|
|
||||||
* this using -EAGAIN.
|
|
||||||
*/
|
|
||||||
if (tp->ops) {
|
|
||||||
module_put(tp->ops->owner);
|
|
||||||
err = -EAGAIN;
|
|
||||||
} else {
|
|
||||||
NL_SET_ERR_MSG(extack, "TC classifier not found");
|
|
||||||
err = -ENOENT;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
tp->classify = tp->ops->classify;
|
tp->classify = tp->ops->classify;
|
||||||
|
Loading…
Reference in New Issue
Block a user