From: Mr NeilBrown Date: Sun, 17 May 2020 23:21:27 +0000 (+1000) Subject: LU-9679 lnet: tidy lnet_discover and fix mem accounting bug. X-Git-Tag: 2.13.54~26 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=45722de60a8fb5fee86a07ce5e3861b31dcedf59;hp=ef9718e8e9cf8fb7f7dedf2ab7ee3f6ba1646108 LU-9679 lnet: tidy lnet_discover and fix mem accounting bug. A recent patch introduce a memory accounting bug because "n_ids" can change between the ALLOC call and the FREE call. With this patch we fix that by ensuring n_ids doesn't change - the current change is not needed. Also: - discard 'max_intf' var. It is always exactly lnet_interfaces_max, so just use that directly. - only copy back the number of interfaces found - report the number of interfaces actually copied. - Move the copy_to_user until after all locks and references are dropped so there is no need to re-take any locks. Test-Parameters: trivial Fixes: b1f6f3becedc ("LU-9679 libcfs: Add CFS_ALLOC_PTR_ARRAY and free") Signed-off-by: Mr NeilBrown Change-Id: Ib807ca4ce5235b28e7ae11d90e1942aff4454cfc Reviewed-on: https://review.whamcloud.com/38644 Tested-by: jenkins Reviewed-by: Shaun Tancheff Tested-by: Maloo Reviewed-by: Chris Horn Reviewed-by: Oleg Drokin --- diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index 41b14f24..05c0cb3 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -4257,7 +4257,6 @@ lnet_discover(struct lnet_process_id id, __u32 force, int cpt; int i; int rc; - int max_intf = lnet_interfaces_max; if (n_ids <= 0 || id.nid == LNET_NID_ANY) @@ -4267,11 +4266,11 @@ lnet_discover(struct lnet_process_id id, __u32 force, id.pid = LNET_PID_LUSTRE; /* - * if the user buffer has more space than the max_intf - * then only fill it up to max_intf + * If the user buffer has more space than the lnet_interfaces_max, + * then only fill it up to lnet_interfaces_max. */ - if (n_ids > max_intf) - n_ids = max_intf; + if (n_ids > lnet_interfaces_max) + n_ids = lnet_interfaces_max; CFS_ALLOC_PTR_ARRAY(buf, n_ids); if (!buf) @@ -4299,11 +4298,6 @@ lnet_discover(struct lnet_process_id id, __u32 force, if (rc) goto out_decref; - /* Peer may have changed. */ - lp = lpni->lpni_peer_net->lpn_peer; - if (lp->lp_nnis < n_ids) - n_ids = lp->lp_nnis; - i = 0; p = NULL; while ((p = lnet_get_next_peer_ni_locked(lp, NULL, p)) != NULL) { @@ -4312,20 +4306,16 @@ lnet_discover(struct lnet_process_id id, __u32 force, if (++i >= n_ids) break; } + rc = i; - lnet_net_unlock(cpt); - - rc = -EFAULT; - if (copy_to_user(ids, buf, n_ids * sizeof(*buf))) - goto out_relock; - rc = n_ids; -out_relock: - lnet_net_lock(cpt); out_decref: lnet_peer_ni_decref_locked(lpni); out: lnet_net_unlock(cpt); + if (rc >= 0) + if (copy_to_user(ids, buf, rc * sizeof(*buf))) + rc = -EFAULT; CFS_FREE_PTR_ARRAY(buf, n_ids); return rc;