sq工程师是做什么的_那些相见恨晚的编程技术-专业工程师必备

本文分享了提高编程效率的一些实用技巧,包括Git的克隆、分支管理、提交操作以及可视化历史记录;Shell中的bash、.bashrc配置、nohup命令和cronjob定时任务;还提到了数据库管理中的SQL与UDF,强调了良好的编程意识对于解决问题的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分享一下我觉得非常实用的编程技术,觉得好用可以点击上方蓝色字体关注

IGit相关

git是分布式管理系统,是多人协同开发利器,常用的命令有:

git clone xxxxx.git # 克隆一个远程仓库

git checkout -b dev # 新建一个dev分支

git add -A && git commit -m "comment" # 提交本次更新

git branch -m old_name new_name # 修改分支名称

git log --graph # 将提交记录可视化,方便查看分支之间的演化关系,如下所示

除上面常用git命令,更高级一点的命令如git merge squash, git rebase可让提交记录看着更清晰简洁

IIShell相关

shell是Linux里的一个概念,意思是系统外面的一层壳,是用户提交命令和系统交互的界面,类似window系统的cmd.

1. shell类型

工作中使用linux系统的人更多一些,常用的shell是bash shell,所以脚本.sh文件开头一般都/bin/bash意思就是使用bash shell解析该脚本。除了bash,其实还有ksh,csh,zsh等shell。

前几年我看了一篇配置zsh+vim+ternimal的博客,于是试了一下,zsh有一点很方便的地方,就是切换路径的时候不用输cd,直接输路径即可,如图:

->这个符号也更简洁美观一点。

2. bashrc

提到shell,需要知道~/.bashrc这个配置文件,shell的环境变量一般在该文件中编辑,每次新建一个shell都从该文件中读配置。如果当前shell中修改了相关变量,使用source命令就可使其直接生效,不用重新打开新的shell。

3. nohup

好多朋友在使用ssh连接远程服务器时会遇到一个情况:在shell意外断开或者窗口关闭时,其中执行的程序不受影响继续执行。试想晚上11点在家登陆服务器启动一个脚步处理数据,此时想关上电脑睡觉,如果直接盖上电脑,那么ssh会断开,程序就挂了,使用nohup命令可避免此问题,一般如下使用:nohup python xxx.py > log 2>&1 &. 其中2>&1 是输出重定向,最后一个&,是放后台执行。

4. crontab

启动一个定时脚步,比如每天晚上12点更新一次数据库,那么可以使用crontab -e启动,默认进入vim编辑器。

5. vim

刚参加工作时的同事都使用vim,于是我也开始用vim从一开始不习惯到现在爱不释手,vim可以解放双手,秒开上万行的文件,而且可以使用vimrc加入各种配置,熟悉之后可大大提高编程效率。在编辑器内使用vs,sq可实现水平、垂直分屏,方便编辑多个文件。

III Sql

不论是后端开发还是算法同学都可能使用分布式数据库如Hive,ODPS处理数据,高效的写出sql也是一项必备技能,除了常规的多表联合查询,熟练掌握UDF(用户自定义函数)在关键时候可以帮到你。普通UDF可以实现一行输入对一行输出,UDAF实现多对一,UDTF实现一对多。很多平台有sdk可以很方便的写UDF,如阿里云中有python sdk,照着模仿很方便就能写出自己的UDF

IV 意识

对,没错!最后一点也是最重要的就是意识。对业务有没有主人翁意识,遇到问题有没有自己上网搜索解决的意识,出现问题有没有及时沟通讨论,据理力争的意识。

---------

喜欢的朋友可以点关注我的微信公众号烟晓寒,分享互联网技术和行业动态

if (udata) { struct virtio_rdma_create_qp_uresp uresp = {}; struct virtio_rdma_ucontext *uctx = rdma_udata_to_drv_context(udata, struct virtio_rdma_ucontext, ibucontext); uint32_t per_size; per_size = sizeof(struct virtio_rdma_cmd_post_send) + sizeof(struct virtio_rdma_sge) * attr->cap.max_send_sge; vqp->usq_buf_size = PAGE_ALIGN(per_size * attr->cap.max_send_wr); vqp->usq_buf = virtio_rdma_init_mmap_entry(vdev, vqp->sq->vq, &vqp->sq_entry, vqp->usq_buf_size, uctx, &uresp.sq_size, &uresp.svq_used_off, &uresp.svq_size, &vqp->usq_dma_addr); if (!vqp->usq_buf) goto out_err; per_size = sizeof(struct virtio_rdma_cmd_post_recv) + sizeof(struct virtio_rdma_sge) * attr->cap.max_recv_sge; vqp->urq_buf_size = PAGE_ALIGN(per_size * attr->cap.max_recv_wr); vqp->urq_buf = virtio_rdma_init_mmap_entry(vdev, vqp->rq->vq, &vqp->rq_entry, vqp->urq_buf_size, uctx, &uresp.rq_size, &uresp.rvq_used_off, &uresp.rvq_size, &vqp->urq_dma_addr); if (!vqp->urq_buf) { // TODO: pop sq entry dma_free_coherent(vdev->vdev->dev.parent, vqp->usq_buf_size, vqp->usq_buf, vqp->usq_dma_addr); goto out_err; } uresp.sq_offset = rdma_user_mmap_get_offset(&vqp->sq_entry->rdma_entry); uresp.sq_phys_addr = vqp->usq_dma_addr; uresp.num_sqe = attr->cap.max_send_wr; uresp.num_svqe = virtqueue_get_vring_size(vqp->sq->vq); uresp.sq_idx = vqp->sq->vq->index; uresp.rq_offset = rdma_user_mmap_get_offset(&vqp->rq_entry->rdma_entry); uresp.rq_phys_addr = vqp->urq_dma_addr; uresp.num_rqe = attr->cap.max_recv_wr; uresp.num_rvqe = virtqueue_get_vring_size(vqp->rq->vq); uresp.rq_idx = vqp->rq->vq->index; uresp.notifier_size = vdev->fast_doorbell ? PAGE_SIZE : 0; uresp.qpn = vqp->qp_handle; if (udata->outlen < sizeof(uresp)) { rc = -EINVAL; goto out_err_u; } rc = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); if (rc) goto out_err_u; } pr_info("%s: qpn 0x%x wq %d rq %d\n", __func__, rsp->qpn, vqp->sq->vq->index, vqp->rq->vq->index); // ret = &vqp->ibqp; ret = 0; goto out; out_err_u: dma_free_coherent(vdev->vdev->dev.parent, vqp->usq_buf_size, vqp->usq_buf, vqp->usq_dma_addr); dma_free_coherent(vdev->vdev->dev.parent, vqp->urq_buf_size, vqp->urq_buf, vqp->urq_dma_addr); rdma_user_mmap_entry_remove(&vqp->sq_entry->rdma_entry); rdma_user_mmap_entry_remove(&vqp->rq_entry->rdma_entry); out_err: kfree(vqp); out: kfree(rsp); kfree(cmd); return ret; }
03-29
<think>嗯,用户给了一段内核代码,看起来是关于虚拟化RDMA(远程直接内存访问)驱动中创建队列对(QP)的处理逻辑。我得先理清楚这段代码的结构和功能。 首先,代码块的条件是if (udata),这说明用户空间提供了数据,需要处理用户态相关的资源分配。里面定义了一个uresp结构体,用于存储用户空间的响应信息。然后通过rdma_udata_to_drv_context获取用户上下文uctx,这可能和RDMA设备的用户态上下文相关。 接下来,计算每个发送队列(SQ)和接收队列(RQ)条目的大小per_size。对于发送队列,per_size是post_send命令结构体的大小加上SGE(分散/聚集条目)的数量乘以每个SGE的大小。然后使用PAGE_ALIGN对齐缓冲区大小,确保其按页对齐,这可能和内存映射有关。接着调用virtio_rdma_init_mmap_entry初始化mmap入口,分配内存并映射到用户空间。如果分配失败,跳转到错误处理。 同样的逻辑处理接收队列,计算urq_buf_size,初始化接收队列的mmap。如果失败,需要释放之前分配的发送队列资源,然后跳转错误处理。这里有一个TODO注释,提示可能需要处理发送队列条目的弹出,但目前还没实现。 之后设置uresp的各个字段,包括偏移量、物理地址、队列大小和索引等。然后检查用户提供的缓冲区是否足够大,如果不够返回错误。接着通过ib_copy_to_udata将uresp复制回用户空间,如果出错同样跳转错误处理。 错误处理部分out_err_u和out_err负责释放已分配的DMA内存、移除mmap条目,并释放相关资源。最后返回ret。 用户可能想了解这段代码的作用,或者遇到问题需要调试。可能的问题包括资源分配失败、内存泄漏、用户空间数据复制错误等。需要关注错误路径的处理是否正确,比如在接收队列分配失败时是否回滚发送队列的资源,是否所有错误分支都正确释放了内存和条目。 另外,代码中使用了DMA内存分配、virtqueue的操作,以及RDMA的用户态mmap机制,需要这些子系统的基础知识才能深入理解。如果用户是在开发或调试类似驱动,可能需要检查硬件兼容性、内存分配大小是否正确,或者是否有竞争条件导致资源泄漏。</think>这段代码是Linux内核中虚拟化RDMA(Remote Direct Memory Access)驱动的一部分,主要用于创建队列对(Queue Pair, QP)的用户态资源初始化。以下是逐步分析: --- ### **代码功能概述** 当用户态调用`ibv_create_qp`创建QP时,内核通过`udata`获取用户态参数并初始化相关资源。这段代码主要处理: 1. **用户态内存映射**:为发送队列(SQ)和接收队列(RQ)分配DMA内存。 2. **用户态响应数据填充**:将队列的物理地址、大小、索引等信息返回用户态。 3. **错误处理**:资源分配失败时的回滚操作。 --- ### **关键步骤解析** #### **1. 用户态上下文获取** ```c struct virtio_rdma_ucontext *uctx = rdma_udata_to_drv_context(udata, ...); ``` - 通过`udata`获取用户态上下文`uctx`,用于后续内存映射操作。 --- #### **2. 发送队列(SQ)初始化** - **计算单条目大小**: ```c per_size = sizeof(struct virtio_rdma_cmd_post_send) + sizeof(struct virtio_rdma_sge) * attr->cap.max_send_sge; ``` 每个发送请求包含命令头(`post_send`)和多个分散/聚集条目(SGE)。 - **分配对齐的内存**: ```c vqp->usq_buf_size = PAGE_ALIGN(per_size * attr->cap.max_send_wr); vqp->usq_buf = virtio_rdma_init_mmap_entry(...); ``` 使用`PAGE_ALIGN`确保内存按页对齐,并通过`virtio_rdma_init_mmap_entry`初始化用户态可访问的mmap条目。 --- #### **3. 接收队列(RQ)初始化** - 逻辑与SQ类似,但使用`post_recv`命令结构体: ```c per_size = sizeof(struct virtio_rdma_cmd_post_recv) + sizeof(struct virtio_rdma_sge) * attr->cap.max_recv_sge; ``` --- #### **4. 填充用户态响应(`uresp`)** ```c uresp.sq_offset = rdma_user_mmap_get_offset(...); uresp.sq_phys_addr = vqp->usq_dma_addr; uresp.num_sqe = attr->cap.max_send_wr; ``` -SQ/RQ的物理地址(`usq_dma_addr`)、偏移量(`sq_offset`)、队列容量(`num_sqe`)等信息写入`uresp`。 - 通过`ib_copy_to_udata`将`uresp`复制到用户态。 --- #### **5. 错误处理** - **资源释放**: ```c dma_free_coherent(...); // 释放DMA内存 rdma_user_mmap_entry_remove(...); // 移除mmap条目 kfree(vqp); // 释放QP结构体 ``` -SQ或RQ初始化失败,需回滚已分配的资源(如DMA内存、mmap条目)。 --- ### **关键数据结构** - **`virtio_rdma_create_qp_uresp`**:用户态响应结构体,包含SQ/RQ的物理地址、大小、索引等信息。 - **`virtio_rdma_ucontext`**:用户态上下文,关联驱动与用户态的内存映射。 - **`virtio_rdma_cmd_post_send/recv`**:描述RDMA操作的命令结构体。 --- ### **潜在问题与注意事项** 1. **内存对齐**:`PAGE_ALIGN`确保内存按页对齐,避免跨页访问问题。 2. **用户态缓冲区大小检查**: ```c if (udata->outlen < sizeof(uresp)) { ... } ``` 防止用户态提供的缓冲区过小导致数据截断。 3. **错误回滚**:RQ初始化失败时需释放SQ资源(但当前代码注释`TODO: pop sq entry`提示可能存在未完全处理的回滚逻辑)。 --- ### **总结** 这段代码是虚拟化RDMA驱动中QP创建的核心逻辑,通过DMA和mmap机制实现用户态与内核态的高效数据交互。重点在于资源分配、内存映射和错误处理的正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值