> -----Original Message-----
> From: Jason Gunthorpe [mailto:jguntho...@obsidianresearch.com]
> Sent: Friday, July 03, 2015 5:38 PM
> To: Wan, Kaike
> Cc: linux-rdma@vger.kernel.org; Fleck, John; Weiny, Ira
> Subject: Re: [PATCH v7 4/4] IB/sa: Route SA pathrecord query through netlink
> 
> On Tue, Jun 30, 2015 at 09:45:55AM -0400, kaike....@intel.com wrote:
> 
> I still think this is long and rambly, but that is mostly a style preference, 
> I
> think you should look at it and remove some of the left over stuff, like we
> really don't need a rough in for other responses at this point.

I will try to remove some of the placeholders to simplify the code.

> 
> > +#define IB_SA_ENABLE_LOCAL_SERVICE 0x00000001
> > +#define IB_SA_CANCEL                       0x00000002
> > +
> > +#define IB_SA_LOCAL_SVC_ENABLED(query) \
> > +   ((query)->flags & IB_SA_ENABLE_LOCAL_SERVICE) #define
> > +IB_SA_ENABLE_LOCAL_SVC(query) \
> > +   ((query)->flags |= IB_SA_ENABLE_LOCAL_SERVICE) #define
> > +IB_SA_DISABLE_LOCAL_SVC(query) \
> > +   ((query)->flags &= ~IB_SA_ENABLE_LOCAL_SERVICE)
> > +
> > +#define IB_SA_QUERY_CANCELLED(query) \
> > +   ((query)->flags & IB_SA_CANCEL)
> > +#define IB_SA_CANCEL_QUERY(query) \
> > +   ((query)->flags |= IB_SA_CANCEL)
> 
> This whole bit is really strange style - if you really want to keep this then 
> at
> least use static inline functions not macros.

Will be changed to use static inline functions.


> 
> 
> > +static struct ib_nl_request_info *
> > +ib_nl_alloc_request(struct ib_sa_query *query) {
> > +   struct ib_nl_request_info *rinfo;
> > +
> > +   rinfo = kzalloc(sizeof(*rinfo), GFP_ATOMIC);
> > +   if (rinfo == NULL)
> > +           return ERR_PTR(-ENOMEM);
> 
> There really seem to be alot of kallocs going on for what is supposed to be a
> performance path.
> 
> I would probably work to fold this into the ib_sa_query allocation, it is 
> just a
> few bytes we can waste that ram if we are not using netlink.

Will do.

> 
> > +   if ((info->comp_mask & IB_SA_PATH_REC_REVERSIBLE) &&
> > +       sa_rec->reversible != 0) {
> > +           if ((info->comp_mask & IB_SA_PATH_REC_NUMB_PATH) &&
> > +               sa_rec->numb_path > 1)
> > +                   val8 = LS_NLA_PATH_USE_ALL;
> > +           else
> > +                   val8 = LS_NLA_PATH_USE_GMP;
> 
> Drop the num_paths stuff, just set USE_GMP, it is confusing. I thought I
> mentioned this already.

Done.

> 
> > +   } else {
> > +           val8 = LS_NLA_PATH_USE_UNIDIRECTIONAL;
> > +   }
> 
> > +   nla_put(skb, RDMA_NLA_F_MANDATORY | LS_NLA_TYPE_PATH_USE,
> sizeof(val8),
> > +           &val8);
> 
> Non-optional attributes should probably go in a non-nested header, possibly
> along with the portGUID/portnum/whatever.
> 
> So the structure would be:
> 
> nlmsghdr
> struct rdma_ls_resolve_path
> {
>   u64 port_guid; // whatever
>   u32 path_use;
> }
> nlattr[IB_SA_PATH_REC_PKEY,...]*
> 
> This is standard layout for netlink messages

That would be the Family header:

struct rdma_ls_resolve_header {
  u8 device_name[64];
  u8 port_num;
 u8 port_use;
};

> 
> > +static int ib_nl_get_path_rec_attrs_len(struct ib_nl_attr_info *info)
> > +{
> > +   /*
> > +    * We need path use attribute no matter reversible or numb_path is
> > +    * set or not, as long as some other fields get set
> > +    */
> > +   if (WARN_ON(len == 0))
> > +           return len;
> 
> The comment is obsolete, and it shouldn't exit without reserving space for
> the mandatory fields.

Here is a check to make sure that at least some of the mandatory comp_mask bits 
are set. If no bits are set (len == 0), the value of 0 is returned and the 
caller will abort the send.


> 
> > +static int ib_nl_send_request(struct ib_nl_request_info *rinfo) {
> > +   struct ib_nl_attr_info info;
> > +   int opcode;
> > +   struct ib_sa_mad *mad;
> > +   unsigned long flags;
> > +   unsigned long delay;
> > +   int ret;
> > +
> > +   mad = rinfo->query->mad_buf->mad;
> > +   switch (mad->mad_hdr.attr_id) {
> > +   case cpu_to_be16(IB_SA_ATTR_PATH_REC):
> > +           opcode = RDMA_NL_LS_OP_RESOLVE;
> > +           mad = rinfo->query->mad_buf->mad;
> > +           info.comp_mask = mad->sa_hdr.comp_mask;
> > +           info.input = rinfo->query->mad_buf->context[1];
> > +           rinfo->query->mad_buf->context[1] = NULL;
> > +           info.len = ib_nl_get_path_rec_attrs_len(&info);
> > +           info.set_attrs = ib_nl_set_path_rec_attrs;
> > +           break;
> 
> So now we put a bunch of stuff in yet another structure and call through a
> function pointer. Rambly, I'd streamline that..

Done.

> 
> > +   struct ib_mad_send_wc mad_send_wc;
> > +   struct ib_sa_mad *mad = NULL;
> > +   const struct nlattr *head, *curr;
> > +   struct ib_path_rec_data  *rec;
> > +   int len, rem;
> > +
> > +   if (query->callback) {
> > +           head = (const struct nlattr *) nlmsg_data(nlh);
> > +           len = nlmsg_len(nlh);
> > +           nla_for_each_attr(curr, head, len, rem) {
> > +                   if (curr->nla_type == LS_NLA_TYPE_PATH_RECORD) {
> > +                           rec = nla_data(curr);
> > +                           if (rec->flags && IB_PATH_PRIMARY) {
> 
> This is still wrong.
> 
> I looked very closely, and it turns out the record you want to find depends on
> the path use that was asked for.
> 
> LS_NLA_PATH_USE_ALL: IB_PATH_PRIMARY | IB_PATH_GMP |
> IB_PATH_BIDIRECTIONAL
> LS_NLA_PATH_USE_GMP: IB_PATH_PRIMARY | IB_PATH_GMP |
> IB_PATH_BIDIRECTIONAL 
> LS_NLA_PATH_USE_UNIDIRECTIONAL:
> IB_PATH_PRIMARY | IB_PATH_OUTBOUND

Good to know that. This info will be used in next revision to search for the 
desired pathrecord.

> 
> > +static inline int ib_nl_is_good_resolve_resp(const struct nlmsghdr
> > +*nlh) {
> > +   const struct nlattr *head, *curr;
> > +   int len, rem;
> > +
> > +   if (nlh->nlmsg_flags & RDMA_NL_LS_F_ERR)
> > +           return 0;
> > +
> > +   if (!(nlh->nlmsg_flags & RDMA_NL_LS_F_OK))
> > +           return 0;
> > +
> > +   if (nlmsg_len(nlh) < nla_attr_size(sizeof(*rec)))
> > +           return 0;
> > +
> > +   head = (const struct nlattr *) nlmsg_data(nlh);
> > +   len = nlmsg_len(nlh);
> > +   nla_for_each_attr(curr, head, len, rem) {
> > +           if (curr->nla_type == LS_NLA_TYPE_PATH_RECORD)
> > +                   return 1;
> > +   }
> 
> As discussed already, this needs to use nla_parse_nested, which should
> eliminate all of this. Do not do nla_for_each_attr here, just look for ERR.

This function is removed since it now checks for ERR only.


> > +static int ib_nl_handle_set_timeout(struct sk_buff *skb,
> > +                               struct netlink_callback *cb)
> > +{
> > +   const struct nlmsghdr *nlh = (struct nlmsghdr *)cb->nlh;
> > +   int timeout, delta, abs_delta;
> > +   const struct nlattr *attr;
> > +   struct rdma_nla_ls_timeout *to_attr;
> > +   unsigned long flags;
> > +   struct ib_nl_request_info *rinfo;
> > +   long delay = 0;
> > +
> > +   if (nlmsg_len(nlh) < nla_attr_size(sizeof(*to_attr)))
> > +           goto settimeout_out;
> 
> All this should be driven by nla_parse

Changed.

> 
> > +   attr = (const struct nlattr *) nlmsg_data(nlh);
> > +   if (attr->nla_type != LS_NLA_TYPE_TIMEOUT ||
> > +       nla_len(attr) != sizeof(*to_attr))
> > +           goto settimeout_out;
> 
> No nested attr, as discussed

Changed.

> 
> There is something weird here, IIRC in netlink a SET should return back
> exactly the same message with the up to date values. (Probably should
> confirm, I'm not 100% on that)

Not sure what you meant here. This is just a SET request from the user 
application. Where does the "return back" come from?

> 
> And I don't think this should be a dump, again, not 100% sure.

Special check is now done in ibnl_rcv_msg to bypass the dump mechanism for 
SET_TIMEOUT request.

Kaike

> 
> I didn't check the locking or a few otherthings, but I did test it out a bit 
> with a
> custom cache userspace client, would like to try again when the protocol is
> fixed up.
> 
> Thanks,
> Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to