On 6/20/19 8:03 AM, Jack Wang wrote:
+#define P1 )
+#define P2 ))
+#define P3 )))
+#define P4 ))))
+#define P(N) P ## N
+
+#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
+#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
+
+#define LIST(...)                                              \
+       __VA_ARGS__,                                            \
+       ({ unknown_type(); NULL; })                             \
+       CAT(P, COUNT_ARGS(__VA_ARGS__))                         \
+
+#define EMPTY()
+#define DEFER(id) id EMPTY()
+
+#define _CASE(obj, type, member)                               \
+       __builtin_choose_expr(                                  \
+       __builtin_types_compatible_p(                           \
+               typeof(obj), type),                             \
+               ((type)obj)->member
+#define CASE(o, t, m) DEFER(_CASE)(o, t, m)
+
+/*
+ * Below we define retrieving of sessname from common IBTRS types.
+ * Client or server related types have to be defined by special
+ * TYPES_TO_SESSNAME macro.
+ */
+
+void unknown_type(void);
+
+#ifndef TYPES_TO_SESSNAME
+#define TYPES_TO_SESSNAME(...) ({ unknown_type(); NULL; })
+#endif
+
+#define ibtrs_prefix(obj)                                      \
+       _CASE(obj, struct ibtrs_con *,  sess->sessname),     \
+       _CASE(obj, struct ibtrs_sess *, sessname),              \
+       TYPES_TO_SESSNAME(obj)                                  \
+       ))

No preprocessor voodoo please. Please remove all of the above and modify the logging statements such that these pass the proper name string as first argument to logging macros.

+struct ibtrs_msg_conn_req {
+       u8              __cma_version; /* Is set to 0 by cma.c in case of
+                                       * AF_IB, do not touch that. */
+       u8              __ip_version;  /* On sender side that should be
+                                       * set to 0, or cma_save_ip_info()
+                                       * extract garbage and will fail. */
+       __le16          magic;
+       __le16          version;
+       __le16          cid;
+       __le16          cid_num;
+       __le16          recon_cnt;
+       uuid_t          sess_uuid;
+       uuid_t          paths_uuid;
+       u8              reserved[12];
+};

Please remove the reserved[] array and check private_data_len in the code that receives the login request.

+/**
+ * struct ibtrs_msg_conn_rsp - Server connection response to the client
+ * @magic:        IBTRS magic
+ * @version:      IBTRS protocol version
+ * @errno:        If rdma_accept() then 0, if rdma_reject() indicates error
+ * @queue_depth:   max inflight messages (queue-depth) in this session
+ * @max_io_size:   max io size server supports
+ * @max_hdr_size:  max msg header size server supports
+ *
+ * NOTE: size is 56 bytes, max possible is 136 bytes, see man rdma_accept().
+ */
+struct ibtrs_msg_conn_rsp {
+       __le16          magic;
+       __le16          version;
+       __le16          errno;
+       __le16          queue_depth;
+       __le32          max_io_size;
+       __le32          max_hdr_size;
+       u8              reserved[40];
+};

Same comment here: please remove the reserved[] array and check private_data_len in the code that processes this data structure.

+static inline int sockaddr_cmp(const struct sockaddr *a,
+                              const struct sockaddr *b)
+{
+       switch (a->sa_family) {
+       case AF_IB:
+               return memcmp(&((struct sockaddr_ib *)a)->sib_addr,
+                             &((struct sockaddr_ib *)b)->sib_addr,
+                             sizeof(struct ib_addr));
+       case AF_INET:
+               return memcmp(&((struct sockaddr_in *)a)->sin_addr,
+                             &((struct sockaddr_in *)b)->sin_addr,
+                             sizeof(struct in_addr));
+       case AF_INET6:
+               return memcmp(&((struct sockaddr_in6 *)a)->sin6_addr,
+                             &((struct sockaddr_in6 *)b)->sin6_addr,
+                             sizeof(struct in6_addr));
+       default:
+               return -ENOENT;
+       }
+}
+
+static inline int sockaddr_to_str(const struct sockaddr *addr,
+                                  char *buf, size_t len)
+{
+       int cnt;
+
+       switch (addr->sa_family) {
+       case AF_IB:
+               cnt = scnprintf(buf, len, "gid:%pI6",
+                       &((struct sockaddr_ib *)addr)->sib_addr.sib_raw);
+               return cnt;
+       case AF_INET:
+               cnt = scnprintf(buf, len, "ip:%pI4",
+                       &((struct sockaddr_in *)addr)->sin_addr);
+               return cnt;
+       case AF_INET6:
+               cnt = scnprintf(buf, len, "ip:%pI6c",
+                         &((struct sockaddr_in6 *)addr)->sin6_addr);
+               return cnt;
+       }
+       cnt = scnprintf(buf, len, "<invalid address family>");
+       pr_err("Invalid address family\n");
+       return cnt;
+}

Since these functions are not in the hot path, please move these into a .c file.

+/**
+ * ibtrs_invalidate_flag() - returns proper flags for invalidation
+ *
+ * NOTE: This function is needed for compat layer, so think twice before
+ *       rename or remove.
+ */
+static inline u32 ibtrs_invalidate_flag(void)
+{
+       return IBTRS_MSG_NEED_INVAL_F;
+}

An inline function that does nothing else than returning a compile-time constant? That does not look useful to me. How about inlining this function?

+#define STAT_STORE_FUNC(type, store, reset)                            \
+static ssize_t store##_store(struct kobject *kobj,                     \
+                            struct kobj_attribute *attr,               \
+                            const char *buf, size_t count)             \
+{                                                                      \
+       int ret = -EINVAL;                                              \
+       type *sess = container_of(kobj, type, kobj_stats);              \
+                                                                       \
+       if (sysfs_streq(buf, "1"))                                    \
+               ret = reset(&sess->stats, true);                 \
+       else if (sysfs_streq(buf, "0"))                                       \
+               ret = reset(&sess->stats, false);                        \
+       if (ret)                                                        \
+               return ret;                                             \
+                                                                       \
+       return count;                                                   \
+}

The above macro concatenates the suffix "_store" to a macro argument with the name 'store'. Please chose a less confusing name for the macro argument. Additionally, using 'reset' for the name of an macro argument that is a function that stores a value seems confusing to me. How about renaming that macro argument into 'set' or 'store_value'?

+#define STAT_SHOW_FUNC(type, show, print)                              \
+static ssize_t show##_show(struct kobject *kobj,                       \
+                          struct kobj_attribute *attr,                 \
+                          char *page)                                  \
+{                                                                      \
+       type *sess = container_of(kobj, type, kobj_stats);              \
+                                                                       \
+       return print(&sess->stats, page, PAGE_SIZE);                     \
+}

Same comment for the macro argument 'show' in the above function.

Thanks,

Bart.

Reply via email to