return is_mbpf_alu(meta) && mbpf_op(meta) == BPF_DIV;
 }
 
+/**
+ * struct nfp_bpf_subprog_info - nfp BPF sub-program (a.k.a. function) info
+ * @stack_depth:       maximum stack depth used by this sub-program
+ */
+struct nfp_bpf_subprog_info {
+       u16 stack_depth;
+};
+
 /**
  * struct nfp_prog - nfp BPF program
  * @bpf: backpointer to the bpf app priv structure
  * @stack_frame_depth: max stack depth for current frame
  * @adjust_head_location: if program has single adjust head call - the insn no.
  * @map_records_cnt: the number of map pointers recorded for this prog
+ * @subprog_cnt: number of sub-programs, including main function
  * @map_records: the map record pointers from bpf->maps_neutral
+ * @subprog: pointer to an array of objects holding info about sub-programs
  * @insns: list of BPF instruction wrappers (struct nfp_insn_meta)
  */
 struct nfp_prog {
        unsigned int adjust_head_location;
 
        unsigned int map_records_cnt;
+       unsigned int subprog_cnt;
        struct nfp_bpf_neutral_map **map_records;
+       struct nfp_bpf_subprog_info *subprog;
 
        struct list_head insns;
 };
 
 {
        struct nfp_insn_meta *meta, *tmp;
 
+       kfree(nfp_prog->subprog);
+
        list_for_each_entry_safe(meta, tmp, &nfp_prog->insns, l) {
                list_del(&meta->l);
                kfree(meta);
 
 
 static int nfp_bpf_finalize(struct bpf_verifier_env *env)
 {
+       struct bpf_subprog_info *info;
+       struct nfp_prog *nfp_prog;
+       int i;
+
+       nfp_prog = env->prog->aux->offload->dev_priv;
+       nfp_prog->subprog_cnt = env->subprog_cnt;
+       nfp_prog->subprog = kcalloc(nfp_prog->subprog_cnt,
+                                   sizeof(nfp_prog->subprog[0]), GFP_KERNEL);
+       if (!nfp_prog->subprog)
+               return -ENOMEM;
+
+       info = env->subprog_info;
+       for (i = 0; i < nfp_prog->subprog_cnt; i++)
+               nfp_prog->subprog[i].stack_depth = info[i].stack_depth;
+
        return 0;
 }