Whamcloud - gitweb
LU-10776 osc: Do not request more than 2GiB grant 33/31533/2
authorPatrick Farrell <paf@cray.com>
Mon, 5 Mar 2018 16:24:32 +0000 (10:24 -0600)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 9 Apr 2018 19:49:18 +0000 (19:49 +0000)
The server enforces a grant limit of 2 GiB, which the
client must honor.  The existing client code combined with
16 MiB RPCs make it possible for the client to ask for
more than this limit.

Make this limit explicit, and also fix an overflow bug in
o_undirty calculation in osc_announce_cached.  (o_undirty
is a 32 bit value and 16 MiB*256 rpcs_in_flight = 4 GiB.
4 GiB + extra grant components overflows o_undirty.)

Cray-bug-id: LUS-5750
Signed-off-by: Patrick Farrell <paf@cray.com>
Change-Id: Ifcb8a9ea7529eae4cd209dc72223ed039c6f6a0d
Reviewed-on: https://review.whamcloud.com/31533
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Nathaniel Clark <nathaniel.l.clark@intel.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Andrew Perepechko <c17827@cray.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/osc/osc_request.c
lustre/target/tgt_grant.c

index 8f90c54..2803aa0 100644 (file)
@@ -1299,6 +1299,8 @@ struct hsm_state_set {
 
 #define OBD_BRW_LOCALS (OBD_BRW_LOCAL1)
 
 
 #define OBD_BRW_LOCALS (OBD_BRW_LOCAL1)
 
+#define OBD_MAX_GRANT 0x7fffffffUL /* Max grant allowed to one client: 2 GiB */
+
 #define OBD_OBJECT_EOF LUSTRE_EOF
 
 #define OST_MIN_PRECREATE 32
 #define OBD_OBJECT_EOF LUSTRE_EOF
 
 #define OST_MIN_PRECREATE 32
index 8ff9021..71948cb 100644 (file)
@@ -671,11 +671,12 @@ static void osc_announce_cached(struct client_obd *cli, struct obdo *oa,
                oa->o_undirty = 0;
        } else {
                unsigned long nrpages;
                oa->o_undirty = 0;
        } else {
                unsigned long nrpages;
+               unsigned long undirty;
 
                nrpages = cli->cl_max_pages_per_rpc;
                nrpages *= cli->cl_max_rpcs_in_flight + 1;
                nrpages = max(nrpages, cli->cl_dirty_max_pages);
 
                nrpages = cli->cl_max_pages_per_rpc;
                nrpages *= cli->cl_max_rpcs_in_flight + 1;
                nrpages = max(nrpages, cli->cl_dirty_max_pages);
-               oa->o_undirty = nrpages << PAGE_SHIFT;
+               undirty = nrpages << PAGE_SHIFT;
                if (OCD_HAS_FLAG(&cli->cl_import->imp_connect_data,
                                 GRANT_PARAM)) {
                        int nrextents;
                if (OCD_HAS_FLAG(&cli->cl_import->imp_connect_data,
                                 GRANT_PARAM)) {
                        int nrextents;
@@ -684,8 +685,13 @@ static void osc_announce_cached(struct client_obd *cli, struct obdo *oa,
                         * grant space */
                        nrextents = (nrpages + cli->cl_max_extent_pages - 1)  /
                                     cli->cl_max_extent_pages;
                         * grant space */
                        nrextents = (nrpages + cli->cl_max_extent_pages - 1)  /
                                     cli->cl_max_extent_pages;
-                       oa->o_undirty += nrextents * cli->cl_grant_extent_tax;
+                       undirty += nrextents * cli->cl_grant_extent_tax;
                }
                }
+               /* Do not ask for more than OBD_MAX_GRANT - a margin for server
+                * to add extent tax, etc.
+                */
+               oa->o_undirty = min(undirty, OBD_MAX_GRANT -
+                                   (PTLRPC_MAX_BRW_PAGES << PAGE_SHIFT)*4UL);
         }
        oa->o_grant = cli->cl_avail_grant + cli->cl_reserved_grant;
         oa->o_dropped = cli->cl_lost_grant;
         }
        oa->o_grant = cli->cl_avail_grant + cli->cl_reserved_grant;
         oa->o_dropped = cli->cl_lost_grant;
index 17da424..8465052 100644 (file)
@@ -894,9 +894,10 @@ static long tgt_grant_alloc(struct obd_export *exp, u64 curgrant,
             tgd->tgd_grant_compat_disable) || left == 0 || exp->exp_failed)
                RETURN(0);
 
             tgd->tgd_grant_compat_disable) || left == 0 || exp->exp_failed)
                RETURN(0);
 
-       if (want > 0x7fffffff) {
-               CERROR("%s: client %s/%p requesting > 2GB grant %llu\n",
-                      obd->obd_name, exp->exp_client_uuid.uuid, exp, want);
+       if (want > OBD_MAX_GRANT) {
+               CERROR("%s: client %s/%p requesting > max (%lu), %llu\n",
+                      obd->obd_name, exp->exp_client_uuid.uuid, exp,
+                      OBD_MAX_GRANT, want);
                RETURN(0);
        }
 
                RETURN(0);
        }