From patchwork Fri Dec 16 10:51:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glauber Costa X-Patchwork-Id: 131803 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id A4EE71007D8 for ; Fri, 16 Dec 2011 21:53:39 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759248Ab1LPKxX (ORCPT ); Fri, 16 Dec 2011 05:53:23 -0500 Received: from mailhub.sw.ru ([195.214.232.25]:36288 "EHLO relay.sw.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758846Ab1LPKxG (ORCPT ); Fri, 16 Dec 2011 05:53:06 -0500 Received: from straightjacket.localdomain ([10.24.20.190]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id pBGAqX78018545; Fri, 16 Dec 2011 13:52:34 +0300 (MSK) From: Glauber Costa To: davem@davemloft.net Cc: linux-kernel@vger.kernel.org, kamezawa.hiroyu@jp.fujitsu.com, netdev@vger.kernel.org, eric.dumazet@gmail.com, cgroups@vger.kernel.org, Glauber Costa , Stephen Rothwell , Randy Dunlap Subject: [PATCH 1/2] net: fix sleeping while atomic problem in sock mem_cgroup. Date: Fri, 16 Dec 2011 14:51:59 +0400 Message-Id: <1324032720-13752-1-git-send-email-glommer@parallels.com> X-Mailer: git-send-email 1.7.6.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org We can't scan the proto_list to initialize sock cgroups, as it holds a rwlock, and we also want to keep the code generic enough to avoid calling the initialization functions of protocols directly, Convert proto_list_lock into a mutex, so we can sleep and do the necessary allocations. This lock is seldom taken, so there shouldn't be any performance penalties associated with that Signed-off-by: Glauber Costa CC: Hiroyouki Kamezawa CC: David S. Miller CC: Eric Dumazet CC: Stephen Rothwell CC: Randy Dunlap --- net/core/sock.c | 28 ++++++++++++++-------------- 1 files changed, 14 insertions(+), 14 deletions(-) diff --git a/net/core/sock.c b/net/core/sock.c index 5a6a906..0c67fac 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -136,7 +136,7 @@ #include #endif -static DEFINE_RWLOCK(proto_list_lock); +static DEFINE_MUTEX(proto_list_mutex); static LIST_HEAD(proto_list); #ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM @@ -145,7 +145,7 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss) struct proto *proto; int ret = 0; - read_lock(&proto_list_lock); + mutex_lock(&proto_list_mutex); list_for_each_entry(proto, &proto_list, node) { if (proto->init_cgroup) { ret = proto->init_cgroup(cgrp, ss); @@ -154,13 +154,13 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss) } } - read_unlock(&proto_list_lock); + mutex_unlock(&proto_list_mutex); return ret; out: list_for_each_entry_continue_reverse(proto, &proto_list, node) if (proto->destroy_cgroup) proto->destroy_cgroup(cgrp, ss); - read_unlock(&proto_list_lock); + mutex_unlock(&proto_list_mutex); return ret; } @@ -168,11 +168,11 @@ void mem_cgroup_sockets_destroy(struct cgroup *cgrp, struct cgroup_subsys *ss) { struct proto *proto; - read_lock(&proto_list_lock); + mutex_lock(&proto_list_mutex); list_for_each_entry_reverse(proto, &proto_list, node) if (proto->destroy_cgroup) proto->destroy_cgroup(cgrp, ss); - read_unlock(&proto_list_lock); + mutex_unlock(&proto_list_mutex); } #endif @@ -2479,10 +2479,10 @@ int proto_register(struct proto *prot, int alloc_slab) } } - write_lock(&proto_list_lock); + mutex_lock(&proto_list_mutex); list_add(&prot->node, &proto_list); assign_proto_idx(prot); - write_unlock(&proto_list_lock); + mutex_unlock(&proto_list_mutex); return 0; out_free_timewait_sock_slab_name: @@ -2505,10 +2505,10 @@ EXPORT_SYMBOL(proto_register); void proto_unregister(struct proto *prot) { - write_lock(&proto_list_lock); + mutex_lock(&proto_list_mutex); release_proto_idx(prot); list_del(&prot->node); - write_unlock(&proto_list_lock); + mutex_unlock(&proto_list_mutex); if (prot->slab != NULL) { kmem_cache_destroy(prot->slab); @@ -2531,9 +2531,9 @@ EXPORT_SYMBOL(proto_unregister); #ifdef CONFIG_PROC_FS static void *proto_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(proto_list_lock) + __acquires(proto_list_mutex) { - read_lock(&proto_list_lock); + mutex_lock(&proto_list_mutex); return seq_list_start_head(&proto_list, *pos); } @@ -2543,9 +2543,9 @@ static void *proto_seq_next(struct seq_file *seq, void *v, loff_t *pos) } static void proto_seq_stop(struct seq_file *seq, void *v) - __releases(proto_list_lock) + __releases(proto_list_mutex) { - read_unlock(&proto_list_lock); + mutex_unlock(&proto_list_mutex); } static char proto_method_implemented(const void *method)