From patchwork Wed Jul 11 13:09:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 1182071 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 753DBDF25A for ; Wed, 11 Jul 2012 13:09:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757427Ab2GKNJq (ORCPT ); Wed, 11 Jul 2012 09:09:46 -0400 Received: from mail-gg0-f174.google.com ([209.85.161.174]:35117 "EHLO mail-gg0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754642Ab2GKNJq (ORCPT ); Wed, 11 Jul 2012 09:09:46 -0400 Received: by gglu4 with SMTP id u4so1170568ggl.19 for ; Wed, 11 Jul 2012 06:09:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=iyn5cJ9Dj8Yp8zQjtPqQA2sWlervK2nXDZyaFoBqt1o=; b=UsD6oulBjXZUuk7AZ4Uf8IoCSppeBb3G9Fxjnbl07Wak+Jc3GShXUaPBj4Q/fg5UB6 8/Gb9tSrmO9xJh27W+fCUM2jCCsidnMo8HWjbeGmZ4WNpRixrpZRzKKQgPBRl+2fyGki r9CzHxPfw64BUcYP6MlZdmrjn7d2kpVZ7QJOTEY2XtCe++DQ1wZauv71pVreFrC6FhWG VNyYEmm9+oHsmEGmlEz1Z3Jny4O+lmRhJuZbGivn+hgLdYXAkNU60hDI6WEFZuZeC8t8 Bl05C3JHwMBwA0hqKono/ROmN4cI5Uxm0I7TEbdT8MLpidbjiF0pfI9SJMNaxZz3XDUv 6VBg== Received: by 10.236.189.9 with SMTP id b9mr54998009yhn.105.1342012185585; Wed, 11 Jul 2012 06:09:45 -0700 (PDT) Received: from salusa.poochiereds.net (cpe-076-182-054-194.nc.res.rr.com. [76.182.54.194]) by mx.google.com with ESMTPS id p14sm1367051ani.8.2012.07.11.06.09.44 (version=SSLv3 cipher=OTHER); Wed, 11 Jul 2012 06:09:44 -0700 (PDT) From: Jeff Layton To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, jiali@redhat.com Subject: [PATCH 1/2] cifs: on CONFIG_HIGHMEM machines, limit the rsize/wsize to the kmap space Date: Wed, 11 Jul 2012 09:09:35 -0400 Message-Id: <1342012176-14783-2-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.7.7.6 In-Reply-To: <1342012176-14783-1-git-send-email-jlayton@redhat.com> References: <1342012176-14783-1-git-send-email-jlayton@redhat.com> X-Gm-Message-State: ALoCoQlNVC3ulzDzl/8ZKKLIPoukYyi3VMdLWEkd39OTpY1wSNIs0QDzG00Hp+hesfsw7F5x3Bo1 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org We currently rely on being able to kmap all of the pages in an async read or write request. If you're on a machine that has CONFIG_HIGHMEM set then that kmap space is limited, sometimes to as low as 512 slots. With 512 slots, we can only support up to a 2M r/wsize, and that's assuming that we can get our greedy little hands on all of them. There are other users however, so it's possible we'll end up stuck with a size that large. Since we can't handle a rsize or wsize larger than that currently, cap those options at the number of kmap slots we have. We could consider capping it even lower, but we currently default to a max of 1M. Might as well allow those luddites on 32 bit arches enough rope to hang themselves. A more robust fix would be to teach the send and receive routines how to contend with an array of pages so we don't need to marshal up a kvec array at all. That's a fairly significant overhaul though, so we'll need this limit in place until that's ready. Cc: Reported-by: Jian Li Signed-off-by: Jeff Layton --- fs/cifs/connect.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 278ca0e..e8c3e6b 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3445,6 +3445,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) +/* + * On hosts with high memory, we can't currently support wsize/rsize that are + * larger than we can kmap at once. Cap the rsize/wsize at + * LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request + * larger than that anyway. + */ +#ifdef CONFIG_HIGHMEM +#define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE) +#else /* CONFIG_HIGHMEM */ +#define CIFS_KMAP_SIZE_LIMIT (1<<24) +#endif /* CONFIG_HIGHMEM */ + static unsigned int cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) { @@ -3475,6 +3487,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) wsize = min_t(unsigned int, wsize, server->maxBuf - sizeof(WRITE_REQ) + 4); + /* limit to the amount that we can kmap at once */ + wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT); + /* hard limit of CIFS_MAX_WSIZE */ wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); @@ -3516,6 +3531,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) if (!(server->capabilities & CAP_LARGE_READ_X)) rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); + /* limit to the amount that we can kmap at once */ + rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT); + /* hard limit of CIFS_MAX_RSIZE */ rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE);