Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

genetlink: push conditional locking into dumpit/done

Add helpers which take/release the genl mutex based
on family->parallel_ops. Remove the separation between
handling of ops in locked and parallel families.

Future patches would make the duplicated code grow even more.

Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20230814214723.2924989-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+35 -55
+35 -55
net/netlink/genetlink.c
··· 52 52 up_write(&cb_lock); 53 53 } 54 54 55 + static void genl_op_lock(const struct genl_family *family) 56 + { 57 + if (!family->parallel_ops) 58 + genl_lock(); 59 + } 60 + 61 + static void genl_op_unlock(const struct genl_family *family) 62 + { 63 + if (!family->parallel_ops) 64 + genl_unlock(); 65 + } 66 + 55 67 static DEFINE_IDR(genl_fam_idr); 56 68 57 69 /* ··· 850 838 851 839 cb->data = info; 852 840 if (ops->start) { 853 - if (!ctx->family->parallel_ops) 854 - genl_lock(); 841 + genl_op_lock(ctx->family); 855 842 rc = ops->start(cb); 856 - if (!ctx->family->parallel_ops) 857 - genl_unlock(); 843 + genl_op_unlock(ctx->family); 858 844 } 859 845 860 846 if (rc) { ··· 863 853 return rc; 864 854 } 865 855 866 - static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 856 + static int genl_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 867 857 { 868 - const struct genl_split_ops *ops = &genl_dumpit_info(cb)->op; 858 + const struct genl_dumpit_info *info = genl_dumpit_info(cb); 859 + const struct genl_split_ops *ops = &info->op; 869 860 int rc; 870 861 871 - genl_lock(); 862 + genl_op_lock(info->family); 872 863 rc = ops->dumpit(skb, cb); 873 - genl_unlock(); 864 + genl_op_unlock(info->family); 874 865 return rc; 875 866 } 876 867 877 - static int genl_lock_done(struct netlink_callback *cb) 868 + static int genl_done(struct netlink_callback *cb) 878 869 { 879 870 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 880 871 const struct genl_split_ops *ops = &info->op; 881 872 int rc = 0; 882 873 883 874 if (ops->done) { 884 - genl_lock(); 875 + genl_op_lock(info->family); 885 876 rc = ops->done(cb); 886 - genl_unlock(); 877 + genl_op_unlock(info->family); 887 878 } 888 - genl_family_rcv_msg_attrs_free(info->attrs); 889 - genl_dumpit_info_free(info); 890 - return rc; 891 - } 892 - 893 - static int genl_parallel_done(struct netlink_callback *cb) 894 - { 895 - const struct genl_dumpit_info *info = genl_dumpit_info(cb); 896 - const struct genl_split_ops *ops = &info->op; 897 - int rc = 0; 898 - 899 - if (ops->done) 900 - rc = ops->done(cb); 901 879 genl_family_rcv_msg_attrs_free(info->attrs); 902 880 genl_dumpit_info_free(info); 903 881 return rc; ··· 899 901 int hdrlen, struct net *net) 900 902 { 901 903 struct genl_start_context ctx; 904 + struct netlink_dump_control c = { 905 + .module = family->module, 906 + .data = &ctx, 907 + .start = genl_start, 908 + .dump = genl_dumpit, 909 + .done = genl_done, 910 + .extack = extack, 911 + }; 902 912 int err; 903 913 904 914 ctx.family = family; ··· 915 909 ctx.ops = ops; 916 910 ctx.hdrlen = hdrlen; 917 911 918 - if (!family->parallel_ops) { 919 - struct netlink_dump_control c = { 920 - .module = family->module, 921 - .data = &ctx, 922 - .start = genl_start, 923 - .dump = genl_lock_dumpit, 924 - .done = genl_lock_done, 925 - .extack = extack, 926 - }; 927 - 928 - genl_unlock(); 929 - err = __netlink_dump_start(net->genl_sock, skb, nlh, &c); 930 - genl_lock(); 931 - } else { 932 - struct netlink_dump_control c = { 933 - .module = family->module, 934 - .data = &ctx, 935 - .start = genl_start, 936 - .dump = ops->dumpit, 937 - .done = genl_parallel_done, 938 - .extack = extack, 939 - }; 940 - 941 - err = __netlink_dump_start(net->genl_sock, skb, nlh, &c); 942 - } 912 + genl_op_unlock(family); 913 + err = __netlink_dump_start(net->genl_sock, skb, nlh, &c); 914 + genl_op_lock(family); 943 915 944 916 return err; 945 917 } ··· 1049 1065 if (family == NULL) 1050 1066 return -ENOENT; 1051 1067 1052 - if (!family->parallel_ops) 1053 - genl_lock(); 1054 - 1068 + genl_op_lock(family); 1055 1069 err = genl_family_rcv_msg(family, skb, nlh, extack); 1056 - 1057 - if (!family->parallel_ops) 1058 - genl_unlock(); 1070 + genl_op_unlock(family); 1059 1071 1060 1072 return err; 1061 1073 }